Class: ECC::Point
- Inherits:
-
Object
- Object
- ECC::Point
- Defined in:
- lib/elliptic-lite/point.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#x ⇒ Object
readonly
Returns the value of attribute x.
-
#y ⇒ Object
readonly
Returns the value of attribute y.
Class Method Summary collapse
- .[](*args) ⇒ Object
-
.add(*nums) ⇒ Object
convenience helpers - field operations.
- .div(a, b) ⇒ Object
-
.infinity ⇒ Object
convenience helper / shortcut for infinity - in use anywhere? keep? why? why not?.
- .mul(a, b) ⇒ Object
- .on_curve?(x, y) ⇒ Boolean
- .pow(a, exponent) ⇒ Object
- .sub(*nums) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#_add(*nums) ⇒ Object
convenience helpers - field operations.
- #_div(a, b) ⇒ Object
- #_mul(a, b) ⇒ Object
- #_pow(a, exponent) ⇒ Object
- #_sub(*nums) ⇒ Object
- #add(other) ⇒ Object (also: #+)
- #coerce(other) ⇒ Object
-
#curve ⇒ Object
convenience helpers.
-
#curve?(other) ⇒ Boolean
check for matching curver.
-
#double ⇒ Object
double point operation.
- #infinity? ⇒ Boolean
-
#initialize(*args) ⇒ Point
constructor
A new instance of Point.
- #inspect ⇒ Object
-
#mul(coefficient) ⇒ Object
(also: #*)
note: for rmul-style to work needs coerce method to swap s*p to p*s!!.
- #require_curve!(other) ⇒ Object
Constructor Details
#initialize(*args) ⇒ Point
Returns a new instance of Point.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/elliptic-lite/point.rb', line 50 def initialize( *args ) ## allow :infinity or :inf for infinity for now - add more? why? why not? if args.size == 1 && [:inf, :infinity].include?( args[0] ) @x = nil @y = nil elsif args.size == 2 && args[0].is_a?( Integer ) && args[1].is_a?( Integer ) @x, @y = args raise ArgumentError, "point (#{@x}/#{@y}) is NOT on the curve" unless self.class.on_curve?( @x, @y ) else raise ArgumentError, "expected two integer numbers or :inf/:infinity; got #{args.inspect}" end end |
Instance Attribute Details
#x ⇒ Object (readonly)
Returns the value of attribute x.
48 49 50 |
# File 'lib/elliptic-lite/point.rb', line 48 def x @x end |
#y ⇒ Object (readonly)
Returns the value of attribute y.
48 49 50 |
# File 'lib/elliptic-lite/point.rb', line 48 def y @y end |
Class Method Details
.[](*args) ⇒ Object
27 28 29 |
# File 'lib/elliptic-lite/point.rb', line 27 def self.[]( *args ) new( *args ) end |
.add(*nums) ⇒ Object
convenience helpers - field operations
7 8 9 10 |
# File 'lib/elliptic-lite/point.rb', line 7 def self.add( *nums ) ## note: for convenience allow additions of more than two numbers sum = nums.shift ## "pop" first item from array nums.reduce( sum ) {|sum, num| curve.f.add( sum, num ) } end |
.div(a, b) ⇒ Object
17 |
# File 'lib/elliptic-lite/point.rb', line 17 def self.div( a, b ) curve.f.div( a, b ); end |
.infinity ⇒ Object
convenience helper / shortcut for infinity - in use anywhere? keep? why? why not?
31 32 33 |
# File 'lib/elliptic-lite/point.rb', line 31 def self.infinity ## convenience helper / shortcut for infinity - in use anywhere? keep? why? why not? new( :infinity ) end |
.mul(a, b) ⇒ Object
15 |
# File 'lib/elliptic-lite/point.rb', line 15 def self.mul( a, b ) curve.f.mul( a, b ); end |
.on_curve?(x, y) ⇒ Boolean
19 20 21 22 23 24 |
# File 'lib/elliptic-lite/point.rb', line 19 def self.on_curve?( x, y ) ## y**2 == x**3 + curve.a*x + curve.b pow( y, 2 ) == add( pow( x, 3), mul( curve.a, x ), curve.b ) end |
.pow(a, exponent) ⇒ Object
16 |
# File 'lib/elliptic-lite/point.rb', line 16 def self.pow( a, exponent ) curve.f.pow( a, exponent ); end |
.sub(*nums) ⇒ Object
11 12 13 14 |
# File 'lib/elliptic-lite/point.rb', line 11 def self.sub( *nums ) sum = nums.shift ## "pop" first item from array nums.reduce( sum ) {|sum, num| curve.f.sub( sum, num ) } end |
Instance Method Details
#==(other) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/elliptic-lite/point.rb', line 88 def ==( other ) if other.is_a?( Point ) && curve?( other ) @x == other.x && @y == other.y else false end end |
#_add(*nums) ⇒ Object
convenience helpers - field operations
40 |
# File 'lib/elliptic-lite/point.rb', line 40 def _add( *nums ) self.class.add( *nums ); end |
#_div(a, b) ⇒ Object
44 |
# File 'lib/elliptic-lite/point.rb', line 44 def _div( a, b ) self.class.div( a, b ); end |
#_mul(a, b) ⇒ Object
42 |
# File 'lib/elliptic-lite/point.rb', line 42 def _mul( a, b ) self.class.mul( a, b ); end |
#_pow(a, exponent) ⇒ Object
43 |
# File 'lib/elliptic-lite/point.rb', line 43 def _pow( a, exponent ) self.class.pow( a, exponent ); end |
#_sub(*nums) ⇒ Object
41 |
# File 'lib/elliptic-lite/point.rb', line 41 def _sub( *nums ) self.class.sub( *nums ); end |
#add(other) ⇒ Object Also known as: +
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/elliptic-lite/point.rb', line 131 def add( other ) require_curve!( other ) return other if infinity? ## self is infinity/infinity ? return self if other.infinity? ## other is infinity/infinity ? if @x == other.x && @y != other.y return self.class.new( :infinity ) end if @x != other.x ## e.g. add point operation # s = (other.y - @y) / (other.x - @x) # x3 = s**2 - @x - other.x # y3 = s * (@x - x3) - @y s = _div( _sub(other.y, @y), _sub(other.x, @x)) x3 = _sub( _pow(s,2), @x, other.x ) y3 = _sub( _mul( s, _sub(@x, x3)), @y ) return self.class.new( x3, y3 ) end if @x == other.x && @y == other.y ## e.g. double point operation return double end raise "failed to add point #{inspect} to #{other.inspect} - no point addition rules matched; sorry" end |
#coerce(other) ⇒ Object
97 98 99 100 101 102 |
# File 'lib/elliptic-lite/point.rb', line 97 def coerce(other) args = [self, other] ## puts " coerce(#{other} <#{other.class.name}>):" ## pp args args end |
#curve ⇒ Object
convenience helpers
38 |
# File 'lib/elliptic-lite/point.rb', line 38 def curve() self.class.curve; end |
#curve?(other) ⇒ Boolean
check for matching curver
79 80 81 |
# File 'lib/elliptic-lite/point.rb', line 79 def curve?( other ) ## check for matching curver self.curve == other.curve end |
#double ⇒ Object
double point operation
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/elliptic-lite/point.rb', line 163 def double # double point operation if @y == _mul( 0, @x ) self.class.new( :infinity ) else # s = (3 * @x**2 + curve.a) / (2 * @y) # x3 = s**2 - 2 * @x # y3 = s * (@x - x3) - @y s = _div( _add( _mul( 3,_pow(@x, 2)), curve.a), _mul(2, @y)) x3 = _sub( _pow(s, 2), _mul( 2, @x)) y3 = _sub( _mul( s, _sub(@x, x3)), @y) self.class.new( x3, y3 ) end end |
#infinity? ⇒ Boolean
66 67 68 |
# File 'lib/elliptic-lite/point.rb', line 66 def infinity? @x.nil? && @y.nil? end |
#inspect ⇒ Object
70 71 72 73 74 75 76 |
# File 'lib/elliptic-lite/point.rb', line 70 def inspect if infinity? "#{self.class.name}(:infinity)" else "#{self.class.name}(#{@x},#{@y})" end end |
#mul(coefficient) ⇒ Object Also known as: *
note: for rmul-style to work needs coerce method to swap s*p to p*s!!
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/elliptic-lite/point.rb', line 104 def mul( coefficient ) ## note: for rmul-style to work needs coerce method to swap s*p to p*s!! raise ArgumentError, "integer expected for mul; got #{other.class.name}" unless coefficient.is_a?( Integer ) ## todo/check/fix: check for negative integer e.g. -1 etc. ## puts "mul( #{coefficient} <#{coefficient.class.name}>)" =begin result = self.class.new( nil, nil ) coefficient.times do result += self end result =end coef = coefficient current = self result = self.class.new( :infinity ) while coef > 0 result += current if coef.odd? ## if (coef & 0b1) > 0 current = current.double ## double the point coef >>= 1 ## bit shift to the right end result end |
#require_curve!(other) ⇒ Object
83 84 85 |
# File 'lib/elliptic-lite/point.rb', line 83 def require_curve!( other ) raise ArgumentError, "cannot operate on different curves; expected #{self.class.curve} got #{other.class.curve}" unless curve?( other ) end |