summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Le Vaillant <glv@posteo.net>2023-07-04 15:08:04 +0200
committerGuillaume Le Vaillant <glv@posteo.net>2023-07-04 15:08:04 +0200
commit5a467eb18475a577cb532b485f2230c65eff7eeb (patch)
tree94f72a5241941448545eb42bf47ae770162a22d5 /src
parentcf54099ccb7b50b2a37aa7408a9fb7aac671c265 (diff)
Add ec-make-point and ec-destructure-point methods
Diffstat (limited to 'src')
-rw-r--r--src/conditions.lisp12
-rw-r--r--src/public-key/curve25519.lisp25
-rw-r--r--src/public-key/curve448.lisp25
-rw-r--r--src/public-key/ed25519.lisp52
-rw-r--r--src/public-key/ed448.lisp45
-rw-r--r--src/public-key/elliptic-curve.lisp7
-rw-r--r--src/public-key/secp256k1.lisp58
-rw-r--r--src/public-key/secp256r1.lisp58
-rw-r--r--src/public-key/secp384r1.lisp58
-rw-r--r--src/public-key/secp521r1.lisp58
10 files changed, 265 insertions, 133 deletions
diff --git a/src/conditions.lisp b/src/conditions.lisp
index 245c4bc..45b62ab 100644
--- a/src/conditions.lisp
+++ b/src/conditions.lisp
@@ -168,6 +168,18 @@ missing in a call to MAKE-PUBLIC-KEY or MAKE-PRIVATE-KEY."))
(:documentation "Signaled when it is determined that a parameter is
missing in a call to MAKE-MESSAGE."))
+(define-condition missing-point-parameter (ironclad-error)
+ ((kind :initarg :kind :reader kind)
+ (parameter :initarg :parameter :reader parameter)
+ (description :initarg :description :reader description))
+ (:report (lambda (condition stream)
+ (format stream "Missing ~A ~A for ~A point."
+ (description condition)
+ (parameter condition)
+ (kind condition))))
+ (:documentation "Signaled when it is determined that a parameter is
+missing in a call to EC-MAKE-POINT."))
+
(define-condition missing-signature-parameter (ironclad-error)
((kind :initarg :kind :reader kind)
(parameter :initarg :parameter :reader parameter)
diff --git a/src/public-key/curve25519.lisp b/src/public-key/curve25519.lisp
index 0766b13..535ae89 100644
--- a/src/public-key/curve25519.lisp
+++ b/src/public-key/curve25519.lisp
@@ -83,6 +83,20 @@
(multiple-value-setq (x1 z1 x2 z2)
(curve25519-double-and-add x1 z1 x2 z2 x))))))
+(defmethod ec-make-point ((kind (eql :curve25519)) &key x)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'curve25519
+ :parameter 'x
+ :description "coordinate"))
+ (make-instance 'curve25519-point :x x :z 1))
+
+(defmethod ec-destructure-point ((p curve25519-point))
+ (with-slots (x z) p
+ (declare (type integer x z))
+ (let ((x (mod (* x (ec-scalar-inv :curve25519 z)) +curve25519-p+)))
+ (list :x x))))
+
(defmethod ec-encode-scalar ((kind (eql :curve25519)) n)
(integer-to-octets n :n-bits +curve25519-bits+ :big-endian nil))
@@ -95,17 +109,14 @@
x))
(defmethod ec-encode-point ((p curve25519-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
- (with-slots (x z) p
- (declare (type integer x z))
- (let ((x1 (mod (* x (ec-scalar-inv :curve25519 z)) +curve25519-p+)))
- (ec-encode-scalar :curve25519 x1))))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x)))
+ (ec-encode-scalar :curve25519 x)))
(defmethod ec-decode-point ((kind (eql :curve25519)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(let ((x (ldb (byte (1- +curve25519-bits+) 0)
(octets-to-integer octets :big-endian nil))))
- (make-instance 'curve25519-point :x x :z 1)))
+ (ec-make-point :curve25519 :x x)))
(defun curve25519-public-key (sk)
"Compute the public key associated to the private key SK."
diff --git a/src/public-key/curve448.lisp b/src/public-key/curve448.lisp
index 2c74cc2..1615011 100644
--- a/src/public-key/curve448.lisp
+++ b/src/public-key/curve448.lisp
@@ -83,6 +83,20 @@
(multiple-value-setq (x1 z1 x2 z2)
(curve448-double-and-add x1 z1 x2 z2 x))))))
+(defmethod ec-make-point ((kind (eql :curve448)) &key x)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'curve448
+ :parameter 'x
+ :description "coordinate"))
+ (make-instance 'curve448-point :x x :z 1))
+
+(defmethod ec-destructure-point ((p curve448-point))
+ (with-slots (x z) p
+ (declare (type integer x z))
+ (let ((x (mod (* x (ec-scalar-inv :curve448 z)) +curve448-p+)))
+ (list :x x))))
+
(defmethod ec-encode-scalar ((kind (eql :curve448)) n)
(integer-to-octets n :n-bits +curve448-bits+ :big-endian nil))
@@ -95,17 +109,14 @@
x))
(defmethod ec-encode-point ((p curve448-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
- (with-slots (x z) p
- (declare (type integer x z))
- (let ((x1 (mod (* x (ec-scalar-inv :curve448 z)) +curve448-p+)))
- (ec-encode-scalar :curve448 x1))))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x)))
+ (ec-encode-scalar :curve448 x)))
(defmethod ec-decode-point ((kind (eql :curve448)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(let ((x (ldb (byte +curve448-bits+ 0)
(octets-to-integer octets :big-endian nil))))
- (make-instance 'curve448-point :x x :z 1)))
+ (ec-make-point :curve448 :x x)))
(defun curve448-public-key (sk)
"Compute the public key associated to the private key SK."
diff --git a/src/public-key/ed25519.lisp b/src/public-key/ed25519.lisp
index f78bfce..130cb27 100644
--- a/src/public-key/ed25519.lisp
+++ b/src/public-key/ed25519.lisp
@@ -144,6 +144,34 @@
(and (zerop (mod (- (* x1 z2) (* x2 z1)) +ed25519-q+))
(zerop (mod (- (* y1 z2) (* y2 z1)) +ed25519-q+))))))
+(defmethod ec-make-point ((kind (eql :ed25519)) &key x y)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'ed25519
+ :parameter 'x
+ :description "coordinate"))
+ (unless y
+ (error 'missing-point-parameter
+ :kind 'ed25519
+ :parameter 'y
+ :description "coordinate"))
+ (let* ((w (mod (* x y) +ed25519-q+))
+ (p (make-instance 'ed25519-point :x x :y y :z 1 :w w)))
+ (declare (type integer w)
+ (type ed25519-point p))
+ (if (ec-point-on-curve-p p)
+ p
+ (error 'invalid-curve-point :kind 'ed25519))))
+
+(defmethod ec-destructure-point ((p ed25519-point))
+ (with-slots (x y z) p
+ (declare (type integer x y z))
+ (let* ((invz (ec-scalar-inv :ed25519 z))
+ (x (mod (* x invz) +ed25519-q+))
+ (y (mod (* y invz) +ed25519-q+)))
+ (declare (type integer x y invz))
+ (list :x x :y y))))
+
(defmethod ec-encode-scalar ((kind (eql :ed25519)) n)
(integer-to-octets n :n-bits +ed25519-bits+ :big-endian nil))
@@ -151,18 +179,14 @@
(octets-to-integer octets :big-endian nil))
(defmethod ec-encode-point ((p ed25519-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
- (with-slots (x y z) p
- (declare (type integer x y z))
- (let* ((invz (ec-scalar-inv :ed25519 z))
- (x (mod (* x invz) +ed25519-q+))
- (y (mod (* y invz) +ed25519-q+)))
- (declare (type integer x y invz))
- (setf (ldb (byte 1 (- +ed25519-bits+ 1)) y) (ldb (byte 1 0) x))
- (ec-encode-scalar :ed25519 y))))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x))
+ (y (getf coordinates :y)))
+ (declare (type integer x y))
+ (setf (ldb (byte 1 (- +ed25519-bits+ 1)) y) (ldb (byte 1 0) x))
+ (ec-encode-scalar :ed25519 y)))
(defmethod ec-decode-point ((kind (eql :ed25519)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(let* ((y (ec-decode-scalar :ed25519 octets))
(b (ldb (byte 1 (- +ed25519-bits+ 1)) y)))
(declare (type integer y)
@@ -172,13 +196,7 @@
(declare (type integer x))
(unless (= (ldb (byte 1 0) x) b)
(setf x (- +ed25519-q+ x)))
- (let* ((w (mod (* x y) +ed25519-q+))
- (p (make-instance 'ed25519-point :x x :y y :z 1 :w w)))
- (declare (type integer w)
- (type ed25519-point p))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'ed25519))))))
+ (ec-make-point :ed25519 :x x :y y))))
(defun ed25519-hash (&rest messages)
(declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
diff --git a/src/public-key/ed448.lisp b/src/public-key/ed448.lisp
index c060042..b354d53 100644
--- a/src/public-key/ed448.lisp
+++ b/src/public-key/ed448.lisp
@@ -153,6 +153,30 @@
(and (zerop (mod (- (* x1 z2) (* x2 z1)) +ed448-q+))
(zerop (mod (- (* y1 z2) (* y2 z1)) +ed448-q+))))))
+(defmethod ec-make-point ((kind (eql :ed448)) &key x y)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'ed448
+ :parameter 'x
+ :description "coordinate"))
+ (unless y
+ (error 'missing-point-parameter
+ :kind 'ed448
+ :parameter 'y
+ :description "coordinate"))
+ (let ((p (make-instance 'ed448-point :x x :y y :z 1)))
+ (if (ec-point-on-curve-p p)
+ p
+ (error 'invalid-curve-point :kind 'ed448))))
+
+(defmethod ec-destructure-point ((p ed448-point))
+ (with-slots (x y z) p
+ (declare (type integer x y z))
+ (let* ((invz (ec-scalar-inv :ed448 z))
+ (x (mod (* x invz) +ed448-q+))
+ (y (mod (* y invz) +ed448-q+)))
+ (list :x x :y y))))
+
(defmethod ec-encode-scalar ((kind (eql :ed448)) n)
(integer-to-octets n :n-bits +ed448-bits+ :big-endian nil))
@@ -160,18 +184,14 @@
(octets-to-integer octets :big-endian nil))
(defmethod ec-encode-point ((p ed448-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
- (with-slots (x y z) p
- (declare (type integer x y z))
- (let* ((invz (ec-scalar-inv :ed448 z))
- (x (mod (* x invz) +ed448-q+))
- (y (mod (* y invz) +ed448-q+)))
- (declare (type integer x y))
- (setf (ldb (byte 1 (- +ed448-bits+ 1)) y) (ldb (byte 1 0) x))
- (ec-encode-scalar :ed448 y))))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x))
+ (y (getf coordinates :y)))
+ (declare (type integer x y))
+ (setf (ldb (byte 1 (- +ed448-bits+ 1)) y) (ldb (byte 1 0) x))
+ (ec-encode-scalar :ed448 y)))
(defmethod ec-decode-point ((kind (eql :ed448)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(let* ((y (ec-decode-scalar :ed448 octets))
(b (ldb (byte 1 (- +ed448-bits+ 1)) y)))
(setf (ldb (byte 1 (- +ed448-bits+ 1)) y) 0)
@@ -179,10 +199,7 @@
(declare (type integer x))
(unless (= (ldb (byte 1 0) x) b)
(setf x (- +ed448-q+ x)))
- (let ((p (make-instance 'ed448-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'ed448))))))
+ (ec-make-point :ed448 :x x :y y))))
(defun ed448-hash (&rest messages)
(declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
diff --git a/src/public-key/elliptic-curve.lisp b/src/public-key/elliptic-curve.lisp
index 5a1c003..b540f26 100644
--- a/src/public-key/elliptic-curve.lisp
+++ b/src/public-key/elliptic-curve.lisp
@@ -21,6 +21,13 @@
(defgeneric ec-scalar-inv (kind n)
(:documentation "Return the modular inverse of N."))
+(defgeneric ec-make-point (kind &key &allow-other-keys)
+ (:documentation "Return a point of KIND, initialized according to the
+specified coordinates."))
+
+(defgeneric ec-destructure-point (p)
+ (:documentation "Return a plist containing the coordinates of the point P."))
+
(defgeneric ec-encode-scalar (kind n)
(:documentation "Return an octet vector representing the integer N."))
diff --git a/src/public-key/secp256k1.lisp b/src/public-key/secp256k1.lisp
index 3760b53..a267026 100644
--- a/src/public-key/secp256k1.lisp
+++ b/src/public-key/secp256k1.lisp
@@ -136,14 +136,23 @@
(declare (type integer y2 x3 z3 z6 a))
(zerop (mod (- y2 a) +secp256k1-p+)))))
-(defmethod ec-encode-scalar ((kind (eql :secp256k1)) n)
- (integer-to-octets n :n-bits +secp256k1-bits+ :big-endian t))
-
-(defmethod ec-decode-scalar ((kind (eql :secp256k1)) octets)
- (octets-to-integer octets :big-endian t))
+(defmethod ec-make-point ((kind (eql :secp256k1)) &key x y)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'secp256k1
+ :parameter 'x
+ :description "coordinate"))
+ (unless y
+ (error 'missing-point-parameter
+ :kind 'secp256k1
+ :parameter 'y
+ :description "coordinate"))
+ (let ((p (make-instance 'secp256k1-point :x x :y y :z 1)))
+ (if (ec-point-on-curve-p p)
+ p
+ (error 'invalid-curve-point :kind 'secp256k1))))
-(defmethod ec-encode-point ((p secp256k1-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
+(defmethod ec-destructure-point ((p secp256k1-point))
(with-slots (x y z) p
(declare (type integer x y z))
(when (zerop z)
@@ -154,13 +163,24 @@
(invz3 (mod (* invz2 invz) +secp256k1-p+))
(x (mod (* x invz2) +secp256k1-p+))
(y (mod (* y invz3) +secp256k1-p+)))
- (concatenate '(simple-array (unsigned-byte 8) (*))
- (vector 4)
- (ec-encode-scalar :secp256k1 x)
- (ec-encode-scalar :secp256k1 y)))))
+ (list :x x :y y))))
+
+(defmethod ec-encode-scalar ((kind (eql :secp256k1)) n)
+ (integer-to-octets n :n-bits +secp256k1-bits+ :big-endian t))
+
+(defmethod ec-decode-scalar ((kind (eql :secp256k1)) octets)
+ (octets-to-integer octets :big-endian t))
+
+(defmethod ec-encode-point ((p secp256k1-point))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x))
+ (y (getf coordinates :y)))
+ (concatenate '(simple-array (unsigned-byte 8) (*))
+ (vector 4)
+ (ec-encode-scalar :secp256k1 x)
+ (ec-encode-scalar :secp256k1 y))))
(defmethod ec-decode-point ((kind (eql :secp256k1)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(case (aref octets 0)
((2 3)
;; Compressed point
@@ -170,11 +190,8 @@
(y-sign (- (aref octets 0) 2))
(y2 (mod (+ (* x x x) +secp256k1-b+) +secp256k1-p+))
(y (expt-mod y2 +secp256k1-i+ +secp256k1-p+))
- (y (if (= (logand y 1) y-sign) y (- +secp256k1-p+ y)))
- (p (make-instance 'secp256k1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp256k1)))
+ (y (if (= (logand y 1) y-sign) y (- +secp256k1-p+ y))))
+ (ec-make-point :secp256k1 :x x :y y))
(error 'invalid-curve-point :kind 'secp256k1)))
((4)
;; Uncompressed point
@@ -182,11 +199,8 @@
(let* ((x-bytes (subseq octets 1 (1+ (/ +secp256k1-bits+ 8))))
(x (ec-decode-scalar :secp256k1 x-bytes))
(y-bytes (subseq octets (1+ (/ +secp256k1-bits+ 8))))
- (y (ec-decode-scalar :secp256k1 y-bytes))
- (p (make-instance 'secp256k1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp256k1)))
+ (y (ec-decode-scalar :secp256k1 y-bytes)))
+ (ec-make-point :secp256k1 :x x :y y))
(error 'invalid-curve-point :kind 'secp256k1)))
(t
(error 'invalid-curve-point :kind 'secp256k1))))
diff --git a/src/public-key/secp256r1.lisp b/src/public-key/secp256r1.lisp
index 4b6b699..e67ea17 100644
--- a/src/public-key/secp256r1.lisp
+++ b/src/public-key/secp256r1.lisp
@@ -139,14 +139,23 @@
(declare (type integer y2 x3 z2 z4 z6 a))
(zerop (mod (- y2 a) +secp256r1-p+)))))
-(defmethod ec-encode-scalar ((kind (eql :secp256r1)) n)
- (integer-to-octets n :n-bits +secp256r1-bits+ :big-endian t))
-
-(defmethod ec-decode-scalar ((kind (eql :secp256r1)) octets)
- (octets-to-integer octets :big-endian t))
+(defmethod ec-make-point ((kind (eql :secp256r1)) &key x y)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'secp256r1
+ :parameter 'x
+ :description "coordinate"))
+ (unless y
+ (error 'missing-point-parameter
+ :kind 'secp256r1
+ :parameter 'y
+ :description "coordinate"))
+ (let ((p (make-instance 'secp256r1-point :x x :y y :z 1)))
+ (if (ec-point-on-curve-p p)
+ p
+ (error 'invalid-curve-point :kind 'secp256r1))))
-(defmethod ec-encode-point ((p secp256r1-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
+(defmethod ec-destructure-point ((p secp256r1-point))
(with-slots (x y z) p
(declare (type integer x y z))
(when (zerop z)
@@ -157,13 +166,24 @@
(invz3 (mod (* invz2 invz) +secp256r1-p+))
(x (mod (* x invz2) +secp256r1-p+))
(y (mod (* y invz3) +secp256r1-p+)))
- (concatenate '(simple-array (unsigned-byte 8) (*))
- (vector 4)
- (ec-encode-scalar :secp256r1 x)
- (ec-encode-scalar :secp256r1 y)))))
+ (list :x x :y y))))
+
+(defmethod ec-encode-scalar ((kind (eql :secp256r1)) n)
+ (integer-to-octets n :n-bits +secp256r1-bits+ :big-endian t))
+
+(defmethod ec-decode-scalar ((kind (eql :secp256r1)) octets)
+ (octets-to-integer octets :big-endian t))
+
+(defmethod ec-encode-point ((p secp256r1-point))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x))
+ (y (getf coordinates :y)))
+ (concatenate '(simple-array (unsigned-byte 8) (*))
+ (vector 4)
+ (ec-encode-scalar :secp256r1 x)
+ (ec-encode-scalar :secp256r1 y))))
(defmethod ec-decode-point ((kind (eql :secp256r1)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(case (aref octets 0)
((2 3)
;; Compressed point
@@ -173,11 +193,8 @@
(y-sign (- (aref octets 0) 2))
(y2 (mod (+ (* x x x) (* -3 x) +secp256r1-b+) +secp256r1-p+))
(y (expt-mod y2 +secp256r1-i+ +secp256r1-p+))
- (y (if (= (logand y 1) y-sign) y (- +secp256r1-p+ y)))
- (p (make-instance 'secp256r1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp256r1)))
+ (y (if (= (logand y 1) y-sign) y (- +secp256r1-p+ y))))
+ (ec-make-point :secp256r1 :x x :y y))
(error 'invalid-curve-point :kind 'secp256r1)))
((4)
;; Uncompressed point
@@ -185,11 +202,8 @@
(let* ((x-bytes (subseq octets 1 (1+ (/ +secp256r1-bits+ 8))))
(x (ec-decode-scalar :secp256r1 x-bytes))
(y-bytes (subseq octets (1+ (/ +secp256r1-bits+ 8))))
- (y (ec-decode-scalar :secp256r1 y-bytes))
- (p (make-instance 'secp256r1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp256r1)))
+ (y (ec-decode-scalar :secp256r1 y-bytes)))
+ (ec-make-point :secp256r1 :x x :y y))
(error 'invalid-curve-point :kind 'secp256r1)))
(t
(error 'invalid-curve-point :kind 'secp256r1))))
diff --git a/src/public-key/secp384r1.lisp b/src/public-key/secp384r1.lisp
index 9cbd4c8..4ab276d 100644
--- a/src/public-key/secp384r1.lisp
+++ b/src/public-key/secp384r1.lisp
@@ -139,14 +139,23 @@
(declare (type integer y2 x3 z2 z4 z6 a))
(zerop (mod (- y2 a) +secp384r1-p+)))))
-(defmethod ec-encode-scalar ((kind (eql :secp384r1)) n)
- (integer-to-octets n :n-bits +secp384r1-bits+ :big-endian t))
-
-(defmethod ec-decode-scalar ((kind (eql :secp384r1)) octets)
- (octets-to-integer octets :big-endian t))
+(defmethod ec-make-point ((kind (eql :secp384r1)) &key x y)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'secp384r1
+ :parameter 'x
+ :description "coordinate"))
+ (unless y
+ (error 'missing-point-parameter
+ :kind 'secp384r1
+ :parameter 'y
+ :description "coordinate"))
+ (let ((p (make-instance 'secp384r1-point :x x :y y :z 1)))
+ (if (ec-point-on-curve-p p)
+ p
+ (error 'invalid-curve-point :kind 'secp384r1))))
-(defmethod ec-encode-point ((p secp384r1-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
+(defmethod ec-destructure-point ((p secp384r1-point))
(with-slots (x y z) p
(declare (type integer x y z))
(when (zerop z)
@@ -157,13 +166,24 @@
(invz3 (mod (* invz2 invz) +secp384r1-p+))
(x (mod (* x invz2) +secp384r1-p+))
(y (mod (* y invz3) +secp384r1-p+)))
- (concatenate '(simple-array (unsigned-byte 8) (*))
- (vector 4)
- (ec-encode-scalar :secp384r1 x)
- (ec-encode-scalar :secp384r1 y)))))
+ (list :x x :y y))))
+
+(defmethod ec-encode-scalar ((kind (eql :secp384r1)) n)
+ (integer-to-octets n :n-bits +secp384r1-bits+ :big-endian t))
+
+(defmethod ec-decode-scalar ((kind (eql :secp384r1)) octets)
+ (octets-to-integer octets :big-endian t))
+
+(defmethod ec-encode-point ((p secp384r1-point))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x))
+ (y (getf coordinates :y)))
+ (concatenate '(simple-array (unsigned-byte 8) (*))
+ (vector 4)
+ (ec-encode-scalar :secp384r1 x)
+ (ec-encode-scalar :secp384r1 y))))
(defmethod ec-decode-point ((kind (eql :secp384r1)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(case (aref octets 0)
((2 3)
;; Compressed point
@@ -173,11 +193,8 @@
(y-sign (- (aref octets 0) 2))
(y2 (mod (+ (* x x x) (* -3 x) +secp384r1-b+) +secp384r1-p+))
(y (expt-mod y2 +secp384r1-i+ +secp384r1-p+))
- (y (if (= (logand y 1) y-sign) y (- +secp384r1-p+ y)))
- (p (make-instance 'secp384r1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp384r1)))
+ (y (if (= (logand y 1) y-sign) y (- +secp384r1-p+ y))))
+ (ec-make-point :secp384r1 :x x :y y))
(error 'invalid-curve-point :kind 'secp384r1)))
((4)
;; Uncompressed point
@@ -185,11 +202,8 @@
(let* ((x-bytes (subseq octets 1 (1+ (/ +secp384r1-bits+ 8))))
(x (ec-decode-scalar :secp384r1 x-bytes))
(y-bytes (subseq octets (1+ (/ +secp384r1-bits+ 8))))
- (y (ec-decode-scalar :secp384r1 y-bytes))
- (p (make-instance 'secp384r1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp384r1)))
+ (y (ec-decode-scalar :secp384r1 y-bytes)))
+ (ec-make-point :secp384r1 :x x :y y))
(error 'invalid-curve-point :kind 'secp384r1)))
(t
(error 'invalid-curve-point :kind 'secp384r1))))
diff --git a/src/public-key/secp521r1.lisp b/src/public-key/secp521r1.lisp
index 1373e36..3c42c4a 100644
--- a/src/public-key/secp521r1.lisp
+++ b/src/public-key/secp521r1.lisp
@@ -139,14 +139,23 @@
(declare (type integer y2 x3 z2 z4 z6 a))
(zerop (mod (- y2 a) +secp521r1-p+)))))
-(defmethod ec-encode-scalar ((kind (eql :secp521r1)) n)
- (integer-to-octets n :n-bits +secp521r1-bits+ :big-endian t))
-
-(defmethod ec-decode-scalar ((kind (eql :secp521r1)) octets)
- (octets-to-integer octets :big-endian t))
+(defmethod ec-make-point ((kind (eql :secp521r1)) &key x y)
+ (unless x
+ (error 'missing-point-parameter
+ :kind 'secp521r1
+ :parameter 'x
+ :description "coordinate"))
+ (unless y
+ (error 'missing-point-parameter
+ :kind 'secp521r1
+ :parameter 'y
+ :description "coordinate"))
+ (let ((p (make-instance 'secp521r1-point :x x :y y :z 1)))
+ (if (ec-point-on-curve-p p)
+ p
+ (error 'invalid-curve-point :kind 'secp521r1))))
-(defmethod ec-encode-point ((p secp521r1-point))
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
+(defmethod ec-destructure-point ((p secp521r1-point))
(with-slots (x y z) p
(declare (type integer x y z))
(when (zerop z)
@@ -157,13 +166,24 @@
(invz3 (mod (* invz2 invz) +secp521r1-p+))
(x (mod (* x invz2) +secp521r1-p+))
(y (mod (* y invz3) +secp521r1-p+)))
- (concatenate '(simple-array (unsigned-byte 8) (*))
- (vector 4)
- (ec-encode-scalar :secp521r1 x)
- (ec-encode-scalar :secp521r1 y)))))
+ (list :x x :y y))))
+
+(defmethod ec-encode-scalar ((kind (eql :secp521r1)) n)
+ (integer-to-octets n :n-bits +secp521r1-bits+ :big-endian t))
+
+(defmethod ec-decode-scalar ((kind (eql :secp521r1)) octets)
+ (octets-to-integer octets :big-endian t))
+
+(defmethod ec-encode-point ((p secp521r1-point))
+ (let* ((coordinates (ec-destructure-point p))
+ (x (getf coordinates :x))
+ (y (getf coordinates :y)))
+ (concatenate '(simple-array (unsigned-byte 8) (*))
+ (vector 4)
+ (ec-encode-scalar :secp521r1 x)
+ (ec-encode-scalar :secp521r1 y))))
(defmethod ec-decode-point ((kind (eql :secp521r1)) octets)
- (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
(case (aref octets 0)
((2 3)
;; Compressed point
@@ -173,11 +193,8 @@
(y-sign (- (aref octets 0) 2))
(y2 (mod (+ (* x x x) (* -3 x) +secp521r1-b+) +secp521r1-p+))
(y (expt-mod y2 +secp521r1-i+ +secp521r1-p+))
- (y (if (= (logand y 1) y-sign) y (- +secp521r1-p+ y)))
- (p (make-instance 'secp521r1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp521r1)))
+ (y (if (= (logand y 1) y-sign) y (- +secp521r1-p+ y))))
+ (ec-make-point :secp521r1 :x x :y y))
(error 'invalid-curve-point :kind 'secp521r1)))
((4)
;; Uncompressed point
@@ -185,11 +202,8 @@
(let* ((x-bytes (subseq octets 1 (1+ (ceiling +secp521r1-bits+ 8))))
(x (ec-decode-scalar :secp521r1 x-bytes))
(y-bytes (subseq octets (1+ (ceiling +secp521r1-bits+ 8))))
- (y (ec-decode-scalar :secp521r1 y-bytes))
- (p (make-instance 'secp521r1-point :x x :y y :z 1)))
- (if (ec-point-on-curve-p p)
- p
- (error 'invalid-curve-point :kind 'secp521r1)))
+ (y (ec-decode-scalar :secp521r1 y-bytes)))
+ (ec-make-point :secp521r1 :x x :y y))
(error 'invalid-curve-point :kind 'secp521r1)))
(t
(error 'invalid-curve-point :kind 'secp521r1))))