Skip to content

Instantly share code, notes, and snippets.

@richardkiss
Created April 20, 2023 02:42
Show Gist options
  • Save richardkiss/cdce7e95afa66d1dfa3f6ba182a60313 to your computer and use it in GitHub Desktop.
Save richardkiss/cdce7e95afa66d1dfa3f6ba182a60313 to your computer and use it in GitHub Desktop.
(mod V0 ;; V0 should be 0
(include *standard-cl-21*)
;; projective point: ((X . Y) . Z)
(defun-inline x-for-p (POINT) (f (f POINT)))
(defun-inline y-for-p (POINT) (r (f POINT)))
(defun-inline z-for-p (POINT) (r POINT))
; PRIME defines the finite field over X Y and Z (point coordinates)
(defconstant PRIME 0x00fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f)
; some functions to calculate the mod of values
(defun-inline mod-prime (VALUE)
(r (divmod VALUE PRIME))
)
;; double a point
(defun double-point (POINT)
(if POINT
(assign
Y (y-for-p POINT)
;; t = 3*x*x + a*z*z
;; for secp256k1, a is 0, so we elide that term
;; if you adapt this code to a different curve where a≠0
;; you will need edit this function to reintroduce that term
T (mod-prime (* 3 (x-for-p POINT) (x-for-p POINT)))
U (* 2 Y (z-for-p POINT))
V (mod-prime (* 2 U (x-for-p POINT) Y))
W (- (* T T) V V)
U2 (mod-prime (* U U))
(c (c (mod-prime (* U W))
(mod-prime (- (* T (- V W)) (* 2 U2 (* Y Y)))))
(mod-prime (* U U2))
)
)
POINT
)
)
(double-point (c (c (+ V0 0x7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2)
0x56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb)
0x009075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970)
)
)
(mod V0 ;; V0 should be 0
(include *standard-cl-21*)
;; projective point: ((X . Y) . Z)
(defun-inline x-for-p (POINT) (f (f POINT)))
(defun-inline y-for-p (POINT) (r (f POINT)))
(defun-inline z-for-p (POINT) (r POINT))
; PRIME defines the finite field over X Y and Z (point coordinates)
(defconstant PRIME 0x00fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f)
; some functions to calculate the mod of values
(defun-inline mod-prime (VALUE)
(r (divmod VALUE PRIME))
)
;; the code below doubles a point
(defun double-point-tuvwy ((T . U) V W Y U2)
;; double the point given T, U, V, W, Y, U2
(c (c (mod-prime (* U W))
(mod-prime (- (* T (- V W)) (* 2 U2 (* Y Y)))))
(mod-prime (* U U2))
)
)
(defun-inline w-for-tv (T V)
;; calculate w given T and V
(- (* T T) V V)
)
(defun double-point-tuv (POINT TU V)
;; double a point given POINT, T, U and V
(double-point-tuvwy TU V (w-for-tv (f TU) V) (y-for-p POINT) (mod-prime (* (r TU) (r TU))))
)
(defun-inline v-for-point-tu (POINT (T . U))
;; calculate v given POINT, T and U
(mod-prime (* 2 U (x-for-p POINT) (y-for-p POINT)))
)
(defun double-point-tu (POINT TU)
;; double a point given POINT, T and U
(double-point-tuv POINT TU (v-for-point-tu POINT TU))
)
(defun-inline t-for-point (POINT)
;; calculate t given POINT
;; t = 3*x*x + a*z*z
;; for secp256k1, a is 0, so we elide that term
;; if you adapt this code to a different curve where a≠0
;; you will need edit this function to reintroduce that term
(mod-prime (* 3 (x-for-p POINT) (x-for-p POINT)))
)
(defun-inline u-for-point (POINT)
;; calculate u given POINT
(* 2 (y-for-p POINT) (z-for-p POINT))
)
(defun double-point (POINT)
;; double point
(if POINT
(double-point-tu POINT (c (t-for-point POINT) (u-for-point POINT)))
POINT
)
)
(double-point (c (c (+ V0 0x7d152c041ea8e1dc2191843d1fa9db55b68f88fef695e2c791d40444b365afc2)
0x56915849f52cc8f76f5fd7e4bf60db4a43bf633e1b1383f85fe89164bfadcbdb)
0x009075b4ee4d4788cabb49f7f81c221151fa2f68914d0aa833388fa11ff621a970)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment