Class: BitcoinAddrgen::Point
- Inherits:
-
Object
- Object
- BitcoinAddrgen::Point
- Defined in:
- lib/bitcoin_addrgen/addrgen.rb
Instance Attribute Summary collapse
-
#curve ⇒ Object
readonly
Returns the value of attribute curve.
-
#order ⇒ Object
readonly
Returns the value of attribute order.
-
#x ⇒ Object
readonly
Returns the value of attribute x.
-
#y ⇒ Object
readonly
Returns the value of attribute y.
Class Method Summary collapse
- .add(p1, p2) ⇒ Object
- .cmp(p1, p2) ⇒ Object
- .double(p1) ⇒ Object
- .leftmost_bit(x) ⇒ Object
- .mul(x2, p1) ⇒ Object
Instance Method Summary collapse
-
#initialize(curve, x, y, order = nil) ⇒ Point
constructor
A new instance of Point.
Constructor Details
#initialize(curve, x, y, order = nil) ⇒ Point
Returns a new instance of Point.
160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 160 def initialize(curve, x, y, order = nil) @curve = curve @x = x @y = y @order = order if @curve and @curve.instance_of?(Curve) raise Exception, 'Curve does not contain point' if not @curve.contains(@x, @y) if @order != nil raise Exception, 'Self*Order must equal infinity' if (Point.cmp(Point.mul(order, self), :infinity) != 0) end end end |
Instance Attribute Details
#curve ⇒ Object (readonly)
Returns the value of attribute curve.
158 159 160 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 158 def curve @curve end |
#order ⇒ Object (readonly)
Returns the value of attribute order.
158 159 160 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 158 def order @order end |
#x ⇒ Object (readonly)
Returns the value of attribute x.
158 159 160 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 158 def x @x end |
#y ⇒ Object (readonly)
Returns the value of attribute y.
158 159 160 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 158 def y @y end |
Class Method Details
.add(p1, p2) ⇒ Object
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 185 def self.add(p1, p2) return p1 if Point.cmp(p2, :infinity) == 0 and p1.instance_of?(Point) return p2 if Point.cmp(p1, :infinity) == 0 and p2.instance_of?(Point) return :infinity if Point.cmp(p1, :infinity) == 0 and Point.cmp(p2, :infinity) == 0 if Curve.cmp(p1.curve, p2.curve) == 0 if gmp_cmp(p1.x, p2.x) == 0 if gmp_mod(gmp_add(p1.y, p2.y), p1.curve.prime) == 0 return :infinity else return Point.double(p1) end end p = p1.curve.prime l = gmp_mul(gmp_sub(p2.y, p1.y), gmp_invert(gmp_sub(p2.x, p1.x), p)) x3 = gmp_mod(gmp_sub(gmp_sub(gmp_pow(l, 2), p1.x), p2.x), p) y3 = gmp_mod(gmp_sub(gmp_mul(l, gmp_sub(p1.x, x3)), p1.y), p) p3 = Point.new(p1.curve, x3, y3) return p3 else raise Exception, 'Elliptic curves do not match' end end |
.cmp(p1, p2) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 173 def self.cmp(p1, p2) if !p1.instance_of?(Point) return 1 if p2.instance_of?(Point) return 0 if !p2.instance_of?(Point) end if !p2.instance_of?(Point) return 1 if p1.instance_of?(Point) return 0 if !p1.instance_of?(Point) end gmp_cmp(p1.x, p2.x) or gmp_cmp(p1.y, p2.y) or Curve.cmp(p1.curve, p2.curve) end |
.double(p1) ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 240 def self.double(p1) p = p1.curve.prime a = p1.curve.a inverse = gmp_invert(gmp_mul(2, p1.y), p) three_x2 = gmp_mul(3, gmp_pow(p1.x, 2)) l = gmp_mod(gmp_mul(gmp_add(three_x2, a), inverse), p) x3 = gmp_mod(gmp_sub(gmp_pow(l, 2), gmp_mul(2, p1.x)), p) y3 = gmp_mod(gmp_sub(gmp_mul(l, gmp_sub(p1.x, x3)), p1.y), p) y3 = gmp_add(p, y3) if (gmp_cmp(0, y3) > 0) return Point.new(p1.curve, x3, y3) end |
.leftmost_bit(x) ⇒ Object
230 231 232 233 234 235 236 237 238 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 230 def self.leftmost_bit(x) if gmp_cmp(x, 0) > 0 result = gmp_init('1', 10) while gmp_cmp(result, x) <= 0 result = gmp_mul(2, result) end return gmp_div(result, 2) end end |
.mul(x2, p1) ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 210 def self.mul(x2, p1) e = x2 return :infinity if Point.cmp(p1, :infinity) == 0 e = gmp_mod(e, p1.order) if p1.order != nil return :infinity if gmp_cmp(e, 0) == 0 if gmp_cmp(e, 0) > 0 e3 = gmp_mul(3, e) negative_self = Point.new(p1.curve, p1.x, gmp_neg(p1.y), p1.order) i = gmp_div(Point.leftmost_bit(e3), 2) result = p1 while gmp_cmp(i, 1) > 0 result = Point.double(result) result = Point.add(result, p1) if gmp_cmp(gmp_and(e3, i), 0) != 0 and gmp_cmp(gmp_and(e, i), 0) == 0 result = Point.add(result, negative_self) if gmp_cmp(gmp_and(e3, i), 0) == 0 and gmp_cmp(gmp_and(e, i), 0) != 0 i = gmp_div(i, 2) end return result end end |