diff options
author | Guillaume Le Vaillant <glv@posteo.net> | 2023-07-04 15:08:04 +0200 |
---|---|---|
committer | Guillaume Le Vaillant <glv@posteo.net> | 2023-07-04 15:08:04 +0200 |
commit | 5a467eb18475a577cb532b485f2230c65eff7eeb (patch) | |
tree | 94f72a5241941448545eb42bf47ae770162a22d5 /src | |
parent | cf54099ccb7b50b2a37aa7408a9fb7aac671c265 (diff) |
Add ec-make-point and ec-destructure-point methods
Diffstat (limited to 'src')
-rw-r--r-- | src/conditions.lisp | 12 | ||||
-rw-r--r-- | src/public-key/curve25519.lisp | 25 | ||||
-rw-r--r-- | src/public-key/curve448.lisp | 25 | ||||
-rw-r--r-- | src/public-key/ed25519.lisp | 52 | ||||
-rw-r--r-- | src/public-key/ed448.lisp | 45 | ||||
-rw-r--r-- | src/public-key/elliptic-curve.lisp | 7 | ||||
-rw-r--r-- | src/public-key/secp256k1.lisp | 58 | ||||
-rw-r--r-- | src/public-key/secp256r1.lisp | 58 | ||||
-rw-r--r-- | src/public-key/secp384r1.lisp | 58 | ||||
-rw-r--r-- | src/public-key/secp521r1.lisp | 58 |
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)))) |