Skip to content

Commit 3926816

Browse files
committed
[??]:svarga:examples, ecdsa example with signature verification
1 parent ed3be2d commit 3926816

1 file changed

Lines changed: 43 additions & 0 deletions

File tree

examples/ecdsa.jl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
using TinyCrypto
3+
4+
# 1. Define a toy Weierstrass curve over 𝔽₃₁ with G of order 37
5+
curve = Weierstrass(31, 6, 9, 37, 1, (0, 3))
6+
# Weierstrass{𝔽₃₁}: y² = x³ + 6x + 9 | G = (0,3), order = 37, cofactor = 1
7+
8+
# 2. Create a mock blockchain transaction
9+
tx = "hello ethereum"
10+
11+
# 3. Hash it (you fake Keccak256 with H₈ → SHA256 first 8 bytes)
12+
z = Int(H₈(tx)) % curve.order # H₈ returns UInt8; convert to Int for modular arithmetic
13+
14+
# 4. Generate keypair
15+
priv = rand(1:curve.order - 1) # private key is a uniformly random integer in [1, curve order − 1]
16+
pub = priv * curve.G # public key is the scalar multiple of the generator: pub = priv · G
17+
18+
# 5. Sign: create ephemeral scalar `k` and calculate signature (r, s)
19+
k = rand(1:curve.order - 1) # draw a random ephemeral scalar used once per signature
20+
R = k * curve.G # then construct an ephemeral public point R = k·G on the curve
21+
v = isodd(R.point.y.val) ? 1 : 0 # and compute the parity (Ethereum) bit from LSB of y which is used for ECrecover
22+
23+
r = mod(R.point.x, curve.order) # use x-coordinate of R as first signature component
24+
k_inv = invmod(k, curve.order) # compute modular inverse of ephemeral scalar
25+
s = mod(k_inv * (z + r * priv), curve.order) # second signature component s = k⁻¹(z + r·priv) mod n
26+
27+
# 6. The signature is (r, s, v + 27) `27` roots back to early Bitcoin compact signatures, parity bit is used on Ethereum
28+
# whereas Bitcoin uses recovery ID : = {0,1,2,3}
29+
println("Signature: (r = $r, s = $s, v = $(v + 27))")
30+
31+
# 7. Verification
32+
s_inv = invmod(s, curve.order) # compute inverse of signature scalar s⁻¹ mod n
33+
u₁ = z * s_inv % curve.order # u₁ = z · s⁻¹ mod n
34+
u₂ = r * s_inv % curve.order # u₂ = r · s⁻¹ mod n
35+
P = u₁ * curve.G + u₂ * pub # recover point P = u₁·G + u₂·Q (should equal R)
36+
37+
is_valid = mod(P.point.x, curve.order) == r # check if recovered R.x matches r component
38+
println("Signature valid? ", is_valid)
39+
40+
41+
# 8. Recover public key from (r, s, v) and message hash z
42+
# TODO: ECRecover implementation — left as an exercise
43+

0 commit comments

Comments
 (0)