Week 0x7
Crypto
uint64_t bigdiv(uint64_t *num, uint64_t *den, uint64_t *quo, uint64_t *rem) {
return 0;
}
uint64_t bigquo(uint64_t *num, uint64_t *den, uint64_t *quo) {
uint64_t rem[S];
bigdiv(num,den,quo,rem);
return 0;
}
uint64_t bigrem(uint64_t *num, uint64_t *den, uint64_t *rem) {
uint64_t quo[S];
bigdiv(num,den,quo,rem);
return 0;
}
quotient:float = division(dividided:int|float,divisor:int|float)
/
for all values, C /
for float types.quotient:int = division(dividided:int,divisor:int)
//
for int types, C /
for int types.div
, /
, \
, and %
, I used div for “bigdiv” since the others were taken.# i am not about to try to spell "udelcian altoghtn"
def ea(a:int, b:int) -> int:
while min(a,b) != 0:
a, b = max(a,b), min(a,b)
a %= b
return max(a,b)
gcd
, and exist in a world with division and modulo.def
ea(1071, 462)
Subtraction-based animation of the Euclidean algorithm. The initial rectangle has dimensions a = 1071 and b = 462. Squares of size 462×462 are placed within it leaving a 462×147 rectangle. This rectangle is tiled with 147×147 squares until a 21×147 rectangle is left, which in turn is tiled with 21×21 squares, leaving no uncovered area. The smallest square size, 21, is the GCD of 1071 and 462.
>>> 1 << 4096
1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190336
\[ \forall a, b \in \mathbb{Z} : \exists x, y \in \mathbb{Z} : a \times x + b \times y = \gcd(a,b) \]
1
\[ \forall e, \lambda(n) \in \mathbb{Z} : \exists x, y \in \mathbb{Z} : e \times x + \lambda(n) \times y = 1 \]
\[ \forall e, \lambda(n) \in \mathbb{Z} : \exists x \in \mathbb{Z} : e \times x \equiv 1 \pmod{\lambda(n)} \]
extended_gcd
, which I do like.function extended_gcd(a, b)
s := 0; old_s := 1
r := b; old_r := a
while r ≠ 0 do
quotient := old_r div r
(old_r, r) := (r, old_r − quotient × r)
(old_s, s) := (s, old_s − quotient × s)
if b ≠ 0 then
bezout_t := (old_r − old_s × a) div b
else
bezout_t := 0
output "Bézout coefficients:", (old_s, bezout_t)
output "greatest common divisor:", old_r
gcd
is calculable by any implementationb
value we use in the eea.bigmul
& co cannot be used as infix operators.r = m % n # this is a little mul
bigmul(m, n, r) # this is the format of a big mul - not possible in Py
def find_large_prime(k):
is_prime = lambda n : any([n % i for i in range(2, int(n **.5))])
candidate = 6 * k + 1
# you need a prime tester
while not is_prime(candidate):
candidate += 6
return candidate
def extended_gcd(a, b):
if b == 0:
return a, 1, 0
r, s, t = extended_gcd(b, a % b)
return r, t, s - (a // b) * t # no graceful mod here
def lcm(a, b):
return a * b // extended_gcd(a,b)[0]
s = "C" # a random string
m = ord(s) # to number
hide_p = lambda: find_large_prime(1 << 6)
hide_q = lambda: find_large_prime(1 << 7)
n = hide_p() * hide_q()
hide_λ = lambda: lcm(hide_p() - 1, hide_q() - 1)
e = 65537 # encryptor
def find_d():
start = extended_gcd(e,hide_λ())[1]
while start < 0:
start += hide_λ()
return start
def modexp(m, e, n):
if e == 0:
return 1
if e == 1:
return m % n
if e % 2:
return (m * modexp(m*m % n, e//2, n)) % n
return modexp(m*m % n, e//2, n) % n
c = modexp(m, e, n) # ciphertext
new_m = modexp(c % n, find_d(), n)
print(chr(modexp(modexp(ord("C"), e, n), find_d(), n)))