Class: JOSE::JWA::FieldElement

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/jose/jwa/field_element.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x, p) ⇒ FieldElement


6
7
8
9
10
# File 'lib/jose/jwa/field_element.rb', line 6

def initialize(x, p)
  @p = p.to_bn
  @x = x.to_bn % @p
  @x = (@x.to_i % @p).to_bn if @x < 0
end

Instance Attribute Details

#pObject (readonly)

Returns the value of attribute p


4
5
6
# File 'lib/jose/jwa/field_element.rb', line 4

def p
  @p
end

#xObject (readonly)

Returns the value of attribute x


4
5
6
# File 'lib/jose/jwa/field_element.rb', line 4

def x
  @x
end

Class Method Details

.sqrt4k3(x, p) ⇒ Object


141
142
143
# File 'lib/jose/jwa/field_element.rb', line 141

def self.sqrt4k3(x, p)
  return self.new(x.mod_exp(((p+1)/4)[0], p), p)
end

.sqrt8k5(x, p) ⇒ Object


145
146
147
148
149
150
151
152
153
154
# File 'lib/jose/jwa/field_element.rb', line 145

def self.sqrt8k5(x, p)
  y = x.mod_exp(((p+3)/8)[0], p)
  # If the square root exists, it is either y, or y*2^(p-1)/4.
  if y.mod_sqr(p) == (x % p)
    return self.new(y, p)
  else
    z = 2.to_bn.mod_exp(((p-1)/4)[0], p)
    return self.new(y.mod_mul(z, p), p)
  end
end

Instance Method Details

#&(y) ⇒ Object


47
48
49
50
51
# File 'lib/jose/jwa/field_element.rb', line 47

def &(y)
  ival = y.x.to_i if y.is_a?(JOSE::JWA::FieldElement) and check_field_element(y)
  ival ||= y
  return make(@x.to_i & ival)
end

#*(y) ⇒ Object


37
38
39
40
# File 'lib/jose/jwa/field_element.rb', line 37

def *(y)
  check_field_element(y)
  return make(@x*y.x)
end

#**(y) ⇒ Object


23
24
25
26
# File 'lib/jose/jwa/field_element.rb', line 23

def **(y)
  check_field_element(y)
  return make(@x**y.x)
end

#+(y) ⇒ Object


18
19
20
21
# File 'lib/jose/jwa/field_element.rb', line 18

def +(y)
  check_field_element(y)
  return make(@x+y.x)
end

#-(y) ⇒ Object


28
29
30
31
# File 'lib/jose/jwa/field_element.rb', line 28

def -(y)
  check_field_element(y)
  return make(@p+@x-y.x)
end

#[email protected]Object


33
34
35
# File 'lib/jose/jwa/field_element.rb', line 33

def [email protected]
  return make(@p-@x)
end

#/(y) ⇒ Object


42
43
44
45
# File 'lib/jose/jwa/field_element.rb', line 42

def /(y)
  check_field_element(y)
  return self*y.inv()
end

#<<(y) ⇒ Object


69
70
71
72
73
# File 'lib/jose/jwa/field_element.rb', line 69

def <<(y)
  ival = y.x.to_i if y.is_a?(JOSE::JWA::FieldElement) and check_field_element(y)
  ival ||= y
  return make(@x.to_i << ival)
end

#<=>(y) ⇒ Object


12
13
14
15
16
# File 'lib/jose/jwa/field_element.rb', line 12

def <=>(y)
  return nil if not y.is_a?(JOSE::JWA::FieldElement)
  return @p <=> y.p if @p != y.p
  return value <=> y.value
end

#>>(y) ⇒ Object


75
76
77
78
79
# File 'lib/jose/jwa/field_element.rb', line 75

def >>(y)
  ival = y.x.to_i if y.is_a?(JOSE::JWA::FieldElement) and check_field_element(y)
  ival ||= y
  return make(@x.to_i >> ival)
end

#^(y) ⇒ Object


59
60
61
62
63
# File 'lib/jose/jwa/field_element.rb', line 59

def ^(y)
  ival = y.x.to_i if y.is_a?(JOSE::JWA::FieldElement) and check_field_element(y)
  ival ||= y
  return make(@x.to_i ^ ival)
end

#from_bytes(x, b) ⇒ Object

Raises:

  • (ArgumentError)

117
118
119
120
121
122
123
# File 'lib/jose/jwa/field_element.rb', line 117

def from_bytes(x, b)
  x = x.pack(JOSE::JWA::UCHAR_PACK) if x.is_a?(Array)
  rv = OpenSSL::BN.new(x.reverse, 2)# % (2**(b-1))

  raise ArgumentError, "x is larger than or equal to p (#{rv})" if rv >= @p
  return make(rv)
end

#invObject


81
82
83
# File 'lib/jose/jwa/field_element.rb', line 81

def inv
  return make(@x.mod_inverse(@p))
end

#make(ival) ⇒ Object


104
105
106
# File 'lib/jose/jwa/field_element.rb', line 104

def make(ival)
  return JOSE::JWA::FieldElement.new(ival,@p)
end

#negative?Boolean


129
130
131
# File 'lib/jose/jwa/field_element.rb', line 129

def negative?
  return !!(sign.zero? and not zero?)
end

#positive?Boolean


133
134
135
# File 'lib/jose/jwa/field_element.rb', line 133

def positive?
  return !negative?
end

#signObject


108
109
110
# File 'lib/jose/jwa/field_element.rb', line 108

def sign
  return @x%2
end

#sqrObject


85
86
87
# File 'lib/jose/jwa/field_element.rb', line 85

def sqr
  return self*self
end

#sqrtObject


89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/jose/jwa/field_element.rb', line 89

def sqrt
  y = nil
  # Compute candidate square root.
  if (@p % 4) == 3
    y = JOSE::JWA::FieldElement.sqrt4k3(@x,@p)
  elsif (@p % 8) == 5
    y = JOSE::JWA::FieldElement.sqrt8k5(@x,@p)
  else
    raise NotImplementedError, 'sqrt(_,8k+1)'
  end
  # Check square root candidate valid.
  return y if y*y == self
  return nil
end

#to_bytes(b) ⇒ Object


125
126
127
# File 'lib/jose/jwa/field_element.rb', line 125

def to_bytes(b)
  return @x.to_s(2).rjust(b.to_i.div(8), JOSE::JWA::ZERO_PAD).reverse
end

#valueObject


112
113
114
115
# File 'lib/jose/jwa/field_element.rb', line 112

def value
  return (@p-@x)*(-1) if negative?
  return @x
end

#zero?Boolean


137
138
139
# File 'lib/jose/jwa/field_element.rb', line 137

def zero?
  return @x.zero?
end

#|(y) ⇒ Object


53
54
55
56
57
# File 'lib/jose/jwa/field_element.rb', line 53

def |(y)
  ival = y.x.to_i if y.is_a?(JOSE::JWA::FieldElement) and check_field_element(y)
  ival ||= y
  return make(@x.to_i | ival)
end

#[email protected]Object


65
66
67
# File 'lib/jose/jwa/field_element.rb', line 65

def [email protected]
  return make([email protected]x.to_i)
end