-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new generic function for destructuring EC points #61
Conversation
The Do you really need to know the internal representation of points, or is it the "official" curve coordinates that you are interested in? |
Hey @glv2 , Thanks for the quick reply! I have this example JWK public key. {
"kty": "EC",
"use": "sig",
"crv": "P-256",
"kid": "test-id",
"x": "Nyp0YT9NRlY44cULzFiGnWzF_BsaOwyxmsukKkbvuKA",
"y": "joRM15S51FU8NNwMpN03mndkxNcK_5cTOn8bVEBy9KU",
"alg": "ES256"
} In order to decode above key I'm using the following code. (defun decode-secp256r1-pk (data)
"Decodes Secp256r1 (NIST P-256) public key from the given plist data.
See RFC 7518, Section 6.2.1 for more details about Elliptic Curve
public keys format."
(let* ((use (getf data :|use|))
(alg (getf data :|alg|))
(kid (getf data :|kid|))
(kty (getf data :|kty|))
(key-ops (getf data :|key_ops|))
(crv (getf data :|crv|))
(x (getf data :|x|))
(y (getf data :|y|)))
(unless x
(error 'invalid-key :message "Missing X coordinate parameter" :data data))
(unless y
(error 'invalid-key :message "Missing Y coordinate parameter" :data data))
;; The X and Y coordinates are Base64urlUInt-encoded values
(let* ((x-octets (binascii:decode-base64url x))
(y-octets (binascii:decode-base64url y))
(x-uint (ironclad:ec-decode-scalar :secp256r1 x-octets))
(y-uint (ironclad:ec-decode-scalar :secp256r1 y-octets))
(point (make-instance 'ironclad:secp256r1-point :x x-uint :y y-uint :z 1)))
(unless (and (= (length x-octets) 32)
(= (length y-octets) 32))
(error 'invalid-key :message "Coordinates should be 32 bytes for Secp256r1 key" :data data))
(list :use use
:alg alg
:kid kid
:kty kty
:key-ops key-ops
:crv crv
:key (ironclad:make-public-key :secp256r1 :y (ironclad:ec-encode-point point)))))) Then on the REPL: CL-USER> (defparameter *key-plist*
(jonathan:parse (uiop:read-file-string #P"/path/to/ec-public-key.json") :as :plist))
*KEY-PLIST*
CL-USER> (defparameter *parsed-key* (decode-secp256r1-pk *key-plist*))
*PARSED-KEY* Now, in order to encode back the The only way I could do that so far is if get And finally I could use Is there another way I should be approaching this, or is this the way to go? Thanks! |
I added So now you should be able to do: (let* ((coordinates (ec-destructure-point p))
(x-uint (getf coordinates :x))
(y-uint (getf coordinates :y))
...)
(ec-make-point :secp256r1 :x x-uint :y y-uint) Could you give it a try to see if something is missing? |
Hey @glv2 , I'll try it out soon and get back to you. Thanks! |
@glv2 , everything seems to work fine, thanks! |
See [1] for more details. [1]: sharplispers/ironclad#61
Until [1] is merged we will use the unexported symbols [1]: sharplispers/ironclad#61
This PR adds a new generic function -
EC-DESTRUCTURE-POINT
and provides implementation for the existing EC point classes.Also, it exports the various EC point operations and adds slot readers.