module Rb25519

Constants

BASE_XZ
CURVE

Module Methods

Public Class Methods

clamp_string(str) click to toggle source
# File lib/rb-pure25519.rb, line 731
def self.clamp_string(str)
  bytes = str.each_byte.to_a
  bytes[0] &= 248;
  bytes[31] &= 127;
  bytes[31] |= 64;

  return bytes.pack('c*')
end
number_to_string(v) click to toggle source
# File lib/rb-pure25519.rb, line 722
def self.number_to_string(v)
  ary = []
  while v > 0
    ary << (v & 0xFF)
    v >>= 8
  end
  ary.pack('c*')
end
public_key_num(secret) click to toggle source
# File lib/rb-pure25519.rb, line 753
def self.public_key_num(secret)
  if String === secret
    secret = string_to_number(secret)
  end

  xz = CURVE.scale_proj( secret, BASE_XZ )
  (xz[0] / xz[1]).to_i
end
public_key_str(secret) click to toggle source
# File lib/rb-pure25519.rb, line 763
def self.public_key_str(secret)
  number_to_string( public_key_num(secret) )
end
random_secret_num() click to toggle source
# File lib/rb-pure25519.rb, line 746
def self.random_secret_num
  string_to_number(random_secret_str)
end
random_secret_str() click to toggle source
# File lib/rb-pure25519.rb, line 740
def self.random_secret_str
  rv = SecureRandom.random_bytes(32)
  rv = clamp_string(rv)
  rv
end
shared_secret_num(pkey, skey) click to toggle source

Secret is a 'k' in Q = k*P

We want to calculate:

P_shared_secret = (skey + other_skey) * P_base

We get there because:

P_other_pkey = (other_skey) * P_base

So continuing to scale P_other_pkey by `skey` will get us to P_shared_secret. The other party is also doing this calculation; the Abelian group property means this operation is commutative.

Note that the Points are all X points in XZ projective space.

# File lib/rb-pure25519.rb, line 786
def self.shared_secret_num(pkey, skey)
  if String === pkey
    pkey = string_to_number(pkey)
  end
  if String === skey
    skey = string_to_number(skey)
  end

  shared_xz = CURVE.scale_proj( skey, [ CURVE.field[pkey], CURVE.field[1] ] )

  (shared_xz[0] / shared_xz[1]).to_i    # Final projective -> affine inversion
end
shared_secret_str(pkey, skey) click to toggle source
# File lib/rb-pure25519.rb, line 799
def self.shared_secret_str(pkey, skey)
  number_to_string( shared_secret_num(pkey, skey) )
end
string_to_number(val) click to toggle source
# File lib/rb-pure25519.rb, line 714
def self.string_to_number(val)
  v = 0
  val.reverse.each_byte do |byte| 
    v = (v << 8) | byte
  end
  v
end