Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Let's start with definining a finite field (mod 13), that is,
F₁₃ = [0,1,2,3,4,5,6,7,8,9,10,11,12]
where the mod(ulus) is always
a prime number - and the prime number is 13 in this case:
require 'elliptic-lite'
class F₁₃ < FiniteField::Element
def self.prime() 13; end
end
F₁₃.prime #=> 13
F₁₃.include?( 0 ) #=> true
F₁₃.include?( 12 ) #=> true
F₁₃.include?( 13 ) #=> false
Let's try addition, subtraction, multiplication, exponentiation (power), and division
with finite fields
using the class-level add
/sub
/mul
/pow
/div
methods:
F₁₃.add( 7, 12 ) #=> 6
F₁₃.sub( 7, 12 ) #=> 8
F₁₃.mul( 3, 12 ) #=> 10
F₁₃.pow( 3, 3 ) #=> 1
Let's try a finite field (mod 19):
F₁₉ = FiniteField.new(19)
F₁₉.div( 7, 5 ) #=> 9
And optional in a more object-oriented way with
overloaded math operators (+
/-
/*
/**
//
):
a = F₁₃[7]
b = F₁₃[12]
c = F₁₃[6]
a+b == c #=> true
c = F₁₃[8]
a-b == c #=> true
a = F₁₃[3]
b = F₁₃[12]
c = F₁₃[10]
a*b == c #=> true
a = F₁₃[3]
b = F₁₃[1]
a**3 == b #=> true
a*a*a == b #=> true
a*a*a == a**3 #=> true
a = F₁₉[2]
b = F₁₉[7]
c = F₁₉[3]
a/b == c #=> true
# -or-
F₁₃[7] + F₁₃[12] == F₁₃[6]
F₁₃[7] - F₁₃[12] == F₁₃[8]
F₁₃[3] * F₁₃[12] == F₁₃[10]
F₁₃[3] ** 3 == F₁₃[1]
F₁₃[3] * F₁₃[3] * F₁₃[3] == F₁₃[1]
F₁₃[3] ** 3 == F₁₃[3] * F₁₃[3] * F₁₃[3]
F₁₉[2] / F₁₉[7] == F₁₉[3]
Let's define an elliptic curve - y³ = x² + ax + b
where a is 5 and b is 7:
CURVE_5_7 = Curve.new( a: 5, b: 7 )
And let's define a point class - a point being a pair of x/y-coordinates - for the elliptic curve y³ = x² + 5x + 7
(with a=5
and b=7
):
class Point_5_7 < Point
def self.curve() CURVE_5_7; end
end
p1 = Point_5_7.new( -1, -1 ) # point with x/y coords: -1/-1
p2 = Point_5_7.new( -1, -2 ) # raise ArgumentError!! point NOT on curve
Point_5_7.on_curve?( -1, -1 ) #=> true
Point_5_7.on_curve?( -1, -2 ) #=> false
#-or-
p1 = Point_5_7[ -1, -1 ]
p2 = Point_5_7[ -1, -2 ]
# and the infinity point
inf = Point_5_7[ :infinity ]
inf.infinity? #=> true
Let's try point addition on the y³ = x² + 5x + 7
elliptic curve (with a=5
and b=7
):
p1 = Point_5_7[-1, -1]
p2 = Point_5_7[-1, 1]
inf = Point_5_7[ :infinity ]
p1 + inf #=> Point_5_7[-1,-1]
inf + p2 #=> Point_5_7[-1,1]
p1 + p2 #=> Point_5_7[:infinity]
p1 = Point_5_7[ 2, 5]
p2 = Point_5_7[-1,-1]
p1 + p2 #=> Point_5_7[3,-7]
p1 = Point_5_7[-1,-1]
p1 + p1 #=> Point_5_7[18,77]
Let's change from "plain vanilla" integer numbers to finite fields. Let's try F₂₂₃ - a finite field (mod 223) where the mod(ulus) is the prime number 223.
class F₂₂₃ < FiniteField::Element
def self.prime() 223; end
end
Let's define an elliptic curve over F₂₂₃ - y³ = x² + ax + b
where a is 0 and b is 7:
CURVE_F₂₂₃0_7 = Curve.new( a: 0, b: 7, f: F₂₂₃ )
And let's define a point class:
class Point_F₂₂₃0_7 < Point
def self.curve() CURVE_F₂₂₃0_7; end
end
And let's try point addition:
p1 = Point_F₂₂₃0_7[ 192, 105 ]
p2 = Point_F₂₂₃0_7[ 17, 56 ]
p1 + p2 #=> Point_F₂₂₃0_7[170,142]
p1 = Point_F₂₂₃0_7[ 170, 142 ]
p2 = Point_F₂₂₃0_7[ 60, 139 ]
p1 + p2 #=> Point_F₂₂₃0_7[220,181]
p1 = Point_F₂₂₃0_7[ 47, 71 ]
p2 = Point_F₂₂₃0_7[ 17, 56 ]
p1 + p2 #=> Point_F₂₂₃0_7[215,68]
And finally let's try scalar point multiplication:
p = Point_F₂₂₃0_7[ 192, 105 ]
p+p #=> Point_F₂₂₃0_7[49,71]
p = Point_F₂₂₃0_7[ 143, 98 ]
p+p #=> Point_F₂₂₃0_7[64,168]
p = Point_F₂₂₃0_7[ 47, 71 ]
p+p #=> Point_F₂₂₃0_7[36,111]
p+p+p+p #=> Point_F₂₂₃0_7[194,51]
p+p+p+p+p+p+p+p #=> Point_F₂₂₃0_7[116,55]
p+p+p+p+p+p+p+p+p+p+p+p+p+p+p+p+p+p+p+p+p #=> Point_F₂₂₃0_7[:infinity]
#-or-
2*p #=> Point_F₂₂₃0_7[36,111]
4*p #=> Point_F₂₂₃0_7[194,51]
8*p #=> Point_F₂₂₃0_7[116,55]
21*p #=> Point_F₂₂₃0_7[:infinity]
Or let's try the from 1 to inifinity, that is, the order of the group using the generating point (47/71):
p = Point_F₂₂₃0_7[ 47, 71 ]
(1..21).each do |s|
product = s*p
puts " #{s}*#{p.inspect} => #{product.inspect}"
end
resulting in:
1*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[47,71]
2*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[36,111]
3*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[15,137]
4*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[194,51]
5*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[126,96]
6*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[139,137]
7*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[92,47]
8*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[116,55]
9*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[69,86]
10*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[154,150]
11*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[154,73]
12*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[69,137]
13*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[116,168]
14*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[92,176]
15*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[139,86]
16*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[126,127]
17*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[194,172]
18*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[15,86]
19*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[36,112]
20*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[47,152]
21*Point_F₂₂₃0_7[47,71] => Point_F₂₂₃0_7[:infinity]
Let's use the elliptic curve defined by secp256k1 and in use for the public-key cryptography by Dodge, Bitcoin, Ethereum and many others.
secp256k1 refers to the parameters of the elliptic curve. The name represents the specific parameters of curve:
Let's start with the finite field
using a big prime number (almost 2**256), that is,
2**256 - 2**32 - 977
or
115792089237316195423570985008687907853269984665640564039457584007908834671663
:
class S256Field < FiniteField::Element
P = 2**256 - 2**32 - 977
def self.prime() P; end
end
Let's define an elliptic curve over - y³ = x² + ax + b
where a is 0 and b is 7
and let's define a point class:
class S256Point < Point
def self.curve() @curve ||= Curve.new( a: 0, b: 7, f: S256Field ); end
end
And let's define the group for the generation point (g) with the order (n):
SECP256K1 = Group.new(
g: S256Point.new( 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 ),
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
)
That are all the standard secp256k1 parameters to use the Elliptic Curve Digital Signature Algorithm (ECDSA). Let's try to verify a signature (r,s) for a message (z) given a public key (that is, a point on the secp256k1 curve):
pubkey = PublicKey.new( 0x887387e452b8eacc4acfde10d9aaf7f6d9a0f975aabb10d006e4da568744d06c,
0x61de6d95231cd89026e286df3b6ae4a894a3378e393e93a0f45b666329a0ae34 )
# signature 1
z = 0xec208baa0fc1c19f708a9ca96fdeff3ac3f230bb4a7ba4aede4942ad003c0f60
r = 0xac8d1c87e51d0d441be8b3dd5b05c8795b48875dffe00b7ffcfac23010d3a395
s = 0x68342ceff8935ededd102dd876ffd6ba72d6a427a3edb13d26eb0781cb423c4
sig = Signature.new( r, s )
pubkey.verify?( z, sig ) #=> true
# signature 2
z = 0x7c076ff316692a3d7eb3c3bb0f8b1488cf72e1afcd929e29307032997a838a3d
r = 0xeff69ef2b1bd93a66ed5219add4fb51e11a840f404876325a1e8ffe0529a2c
s = 0xc7207fee197d27c618aea621406f6bf5ef6fca38681d82b2f06fddbdce6feab6
sig = Signature.new( r, s )
pubkey.verify?( z, sig ) #=> true
And let's sign a message using a private key (that is, a 256-bit integer of the order (n) of the generation point):
e = 12345 ## private key - note: do NOT use - only for learning
key = PrivateKey.new( e )
z_hex = Digest::SHA256.hexdigest( 'Programming Elliptic Curve Cryptography!' )
z = z_hex.to_i( 16 ) ## convert 256-bit (32-byte) hexstring to (big) integer number
sig = key.sign( z )
sig.r #=> 35839919642726191515862186078164267963984698217861116280002507416364797996230
sig.s #=> 34481949470477153440646085306694123309931748956488082604284303792820502002529
pubkey = key.pubkey ## derive public key from private
# And let's verify signature using public key
pubkey.verify?( z, sig ) #=> true
# -or-
pubkey = PublicKey.new(
0xf01d6b9018ab421dd410404cb869072065522bf85734008f105cf385a023a80f,
0x0eba29d0f0c5408ed681984dc525982abefccd9f7ff01dd26da4999cf3f6a295 )
sig = Signature.new(
35839919642726191515862186078164267963984698217861116280002507416364797996230,
34481949470477153440646085306694123309931748956488082604284303792820502002529 )
pubkey.verify?( z, sig ) #=> true
That's it.
Bitcon Public Service Announcement:
If we all buy Bitcoin from one another at ever higher prices we'll all be rich beyond our wildest dreams.
-- Trolly McTrollface
BEWARE: Yes, Bitcoin Is a Ponzi - Learn How the Investment Fraud Works »
Just install the gem:
$ gem install elliptic-lite
The scripts are dedicated to the public domain. Use it as you please with no restrictions whatsoever.
Send them along to the wwwmake forum. Thanks!
FAQs
Unknown package
We found that elliptic-lite demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.