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.
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 56 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 !@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.
54 55 56 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 54 def curve @curve end |
#order ⇒ Object (readonly)
Returns the value of attribute order.
54 55 56 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 54 def order @order end |
#x ⇒ Object (readonly)
Returns the value of attribute x.
54 55 56 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 54 def x @x end |
#y ⇒ Object (readonly)
Returns the value of attribute y.
54 55 56 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 54 def y @y end |
Class Method Details
.add(p1, p2) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 85 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 p1.x == p2.x if (p1.y + p2.y).fmod(p1.curve.prime) == 0 return :infinity else return Point.double(p1) end end p = p1.curve.prime l = (p2.y - p1.y) * (p2.x - p1.x).invert(p) x3 = (l ** 2 - p1.x - p2.x).fmod(p) y3 = (l * (p1.x - x3) - p1.y).fmod(p) p3 = Point.new(p1.curve, x3, y3) return p3 else raise Exception, 'Elliptic curves do not match' end end |
.cmp(p1, p2) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 69 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 if p1.x == p2.x and p1.y == p2.y and Curve.cmp(p1.curve, p2.curve) return 0 else return 1 end end |
.double(p1) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 140 def self.double(p1) p = p1.curve.prime a = p1.curve.a inverse = (2 * p1.y).invert(p) three_x2 = 3 * (p1.x ** 2) l = ((three_x2 + a) * inverse).fmod(p) x3 = (l ** 2 - 2 * p1.x).fmod(p) y3 = (l * (p1.x - x3) - p1.y).fmod(p) y3 = p + y3 if 0 > y3 p3 = Point.new(p1.curve, x3, y3) p3 end |
.leftmost_bit(x) ⇒ Object
130 131 132 133 134 135 136 137 138 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 130 def self.leftmost_bit(x) if x > GMP::Z.new(0) result = GMP::Z.new(1) while result <= x result *= 2 end return result.tdiv(2) end end |
.mul(x2, p1) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/bitcoin_addrgen/addrgen.rb', line 110 def self.mul(x2, p1) e = x2 return :infinity if Point.cmp(p1, :infinity) == 0 e = e.fmod(p1.order) if p1.order != nil return :infinity if e == GMP::Z.new(0) if e > GMP::Z.new(0) e3 = 3 * e negative_self = Point.new(p1.curve, p1.x, -p1.y, p1.order) i = Point.leftmost_bit(e3).tdiv(2) result = p1 while i > GMP::Z.new(1) result = Point.double(result) result = Point.add(result, p1) if (e3 & i) != GMP::Z.new(0) and (e & i) == GMP::Z.new(0) result = Point.add(result, negative_self) if (e3 & i) == GMP::Z.new(0) and (e & i) != GMP::Z.new(0) i = i.tdiv(2) end return result end end |