Class: BitcoinAddrgen::Point

Inherits:
Object
  • Object
show all
Defined in:
lib/bitcoin_addrgen/addrgen.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(curve, x, y, order = nil) ⇒ Point

Returns a new instance of Point.



185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/bitcoin_addrgen/addrgen.rb', line 185

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

#curveObject (readonly)

Returns the value of attribute curve.



183
184
185
# File 'lib/bitcoin_addrgen/addrgen.rb', line 183

def curve
  @curve
end

#orderObject (readonly)

Returns the value of attribute order.



183
184
185
# File 'lib/bitcoin_addrgen/addrgen.rb', line 183

def order
  @order
end

#xObject (readonly)

Returns the value of attribute x.



183
184
185
# File 'lib/bitcoin_addrgen/addrgen.rb', line 183

def x
  @x
end

#yObject (readonly)

Returns the value of attribute y.



183
184
185
# File 'lib/bitcoin_addrgen/addrgen.rb', line 183

def y
  @y
end

Class Method Details

.add(p1, p2) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/bitcoin_addrgen/addrgen.rb', line 210

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



198
199
200
201
202
203
204
205
206
207
208
# File 'lib/bitcoin_addrgen/addrgen.rb', line 198

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



265
266
267
268
269
270
271
272
273
274
275
# File 'lib/bitcoin_addrgen/addrgen.rb', line 265

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



255
256
257
258
259
260
261
262
263
# File 'lib/bitcoin_addrgen/addrgen.rb', line 255

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



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/bitcoin_addrgen/addrgen.rb', line 235

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