class ECC::Point
Attributes
x[R]
y[R]
Public Class Methods
[]( *args )
click to toggle source
# File lib/elliptic-lite/point.rb, line 27 def self.[]( *args ) new( *args ) end
add( *nums )
click to toggle source
convenience helpers - field operations
# 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 )
click to toggle source
# File lib/elliptic-lite/point.rb, line 17 def self.div( a, b ) curve.f.div( a, b ); end
infinity()
click to toggle source
# 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 )
click to toggle source
# File lib/elliptic-lite/point.rb, line 15 def self.mul( a, b ) curve.f.mul( a, b ); end
new( *args )
click to toggle source
# 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
on_curve?( x, y )
click to toggle source
# 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 )
click to toggle source
# File lib/elliptic-lite/point.rb, line 16 def self.pow( a, exponent ) curve.f.pow( a, exponent ); end
sub( *nums )
click to toggle source
# 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
Public Instance Methods
==( other )
click to toggle source
# 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 )
click to toggle source
convenience helpers - field operations
# File lib/elliptic-lite/point.rb, line 40 def _add( *nums ) self.class.add( *nums ); end
_div( a, b )
click to toggle source
# File lib/elliptic-lite/point.rb, line 44 def _div( a, b ) self.class.div( a, b ); end
_mul( a, b )
click to toggle source
# File lib/elliptic-lite/point.rb, line 42 def _mul( a, b ) self.class.mul( a, b ); end
_pow( a, exponent )
click to toggle source
# File lib/elliptic-lite/point.rb, line 43 def _pow( a, exponent ) self.class.pow( a, exponent ); end
_sub( *nums )
click to toggle source
# File lib/elliptic-lite/point.rb, line 41 def _sub( *nums ) self.class.sub( *nums ); end
add( other )
click to toggle source
# 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
Also aliased as: +
coerce(other)
click to toggle source
# 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()
click to toggle source
convenience helpers
# File lib/elliptic-lite/point.rb, line 38 def curve() self.class.curve; end
curve?( other )
click to toggle source
# File lib/elliptic-lite/point.rb, line 79 def curve?( other ) ## check for matching curver self.curve == other.curve end
double()
click to toggle source
# 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?()
click to toggle source
# File lib/elliptic-lite/point.rb, line 66 def infinity? @x.nil? && @y.nil? end
inspect()
click to toggle source
# 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 )
click to toggle source
# 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
Also aliased as: *
require_curve!( other )
click to toggle source
# 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