Algorithm to add two digits to the end of a number to calculate a specific modulus? - modulo

So, lets say I have a number 123456. 123456 % 97 = 72. How can I determine what two digits need to be added to the end of 123456 such that the new number % 97 = 1? Note--it must always be two digits.
For example, 12345676 % 97 = 1. In this case, I need to add the digits "76" to the end of the number.
(This is for IBAN number calculation.)

x = 123456
x = x * 100
newX = x + 1 + 97 - (x % 97)
Edit: put the 100 in the wrong place

You calc the modulo of 12345600 to 97 and add (97 - that + 1) to that number.
So you get what RoBorg explained whay cleaner above :)

This is the equation that that you need
X = Y -(Number*100 mod y) - 1
where:
Number = 123456
Y = 97
X the number you need

Let’s say we have to receive the number containing 12 digits.
Step 1:
Write any random number of 10 digits, i.e. 2 digits less than needed, e.g. 1234567890 – this is X
Step 2:
X * 100 = 123456789000.
‘123456789000’ - this is Y
Step 3:
Y / 97 = '1272750402.061856'.
'06' – this is Z
Step 4:
97 – Z + 1 = 92.
'92' – this is W
Step 5:
Final Deal Number is X followed by W, i.e. '123456789092'
Examples of accepted numbers:
100000000093
100000000190
100000000287
Etc.

Modulo arithmetic is really not that different from regular arithmetic. The key to solving the kind of problem that you're having is to realize that what you would normally do to solve that problem is still valid (in what follows, any mention of number means integer number):
Say you have
15 + x = 20
The way that you solve this is by realizing that the inverse of 15 under regular addition is -15 then you can write (exploiting commutativity and associativity as we naturally do)
15 + x + (-15) = (15 + (-15)) + x = 0 + x = x = 20 + (-15) = 5
so that your answer is x = 5
Now on to your problem.
Say that N and M are known, and you're looking for x under addition modulo k:
( N + x ) mod k = M
First realize that
( N + x ) mod k = ( ( N mod k ) + ( x mod k ) ) mod k
and for the problem to make sense
M mod k = M
and
x mod k = x
so that by letting
N mod k = N_k
and
( a + b ) mod k = a +_k b
you have
N_k +_k x = M
which means that what you need is the inverse of N_k under +_k. This is actually pretty simple because the inverse under +_k is whatever satisfies this equation:
N_k +_k ("-N_k") = 0
which is actually pretty simple because for a number y such that 0 <= y < k
(y + (k - y)) mod k = k mod k = 0
so that
"-N_k" = (k-N_k)
and then
N_k +_k x +_k "-N_k" = N_k +_k "-N_k" +_k x = 0 +_k x = x = M +_k "-N_k" = M +_k ( k - N_k )
so that the solution to
( N + x ) mod k = M
is
x = ( M + ( k - ( N mod k ) ) ) mod k
and for your problem in particular
( 12345600 + x ) % 97 = 1
is solved by
x = ( 1 + ( 97 - ( 12345600 mod 97 ) ) ) mod 97 = 76
Do notice that the requirement that you solution always have two digits is built in as long as k < 100

Related

Substitute variable in Maxima

newbie Maxima question
I have a transfer function in Maxima
E1 : y = K_i*s/(s^2 + w^2);
I'd like to have the closed-form of the equation affter applying the bilinear transform
E2 : s = (2/Ts*(z-1)/(z+1));
I would like to get the transfer function for z, by substituing s by equation E2. How should I proceed?
Regards
Note that subst can apply one or more substitutions stated as equations. In this case, try subst(E2, E1).
That will probably create a messy result -- you can simplify it somewhat by applying ratsimp to the result.
Here's what I get from that.
(%i2) E1 : y = K_i*s/(s^2 + w^2);
K_i s
(%o2) y = -------
2 2
w + s
(%i3) E2 : s = (2/Ts*(z-1)/(z+1));
2 (z - 1)
(%o3) s = ----------
Ts (z + 1)
(%i4) subst (E2, E1);
2 K_i (z - 1)
(%o4) y = ------------------------------
2
4 (z - 1) 2
Ts (z + 1) (------------ + w )
2 2
Ts (z + 1)
(%i5) ratsimp (%);
2
2 K_i Ts z - 2 K_i Ts
(%o5) y = -----------------------------------------------
2 2 2 2 2 2 2
(Ts w + 4) z + (2 Ts w - 8) z + Ts w + 4

Construct DFA for L = {(na(w)-nb(w)) mod 3>0}

As per the title:
L = {(na(w)-nb(w)) mod 3>0}
Alphabet = {a,b}
I found two answers to this problem:
In this solution, our language is accepted.
However,
w = b
is accepted as well.
In the next solution:
Our problem of
w = b
is solved here but
w = aaab
is not accepted.
How do I approach this problem? I couldn't find a suitable answer for it on the internet.
Assume we have the following definition of mod:
x mod y = { x, if 0 <= x < y
(x - y) mod y, if 0 < y <= x
x, if -y < x < 0
(x + y) mod y, if x <= -y < 0
-(-x mod -y) if y < 0
}
So our modulus works like this:
3 mod 5 = 3
6 mod 5 = 6-5 mod 5 = 1 mod 5 = 1
-3 mod 5 = -3
-6 mod 5 = -6+5 mod 5 = -1 mod 5 = -1
-6 mod -5 = -(6 mod 5) = -1
6 mod -5 = -(-6 mod 5) = -(-1) = 1
Our language is L = {(n_a(w) - n_b(w)) mod 3 > 0}
Let's define A := n_a(w) and B := n_b(w). So we need to solve (A - B) mod 3 > 0 using our definition of mod. We have five cases:
if 0 <= A - B < 3, meaning B <= A < B + 3, then (A - B) mod 3 = A - B. By hypothesis it is at least zero, and can only be zero then if A = B. We can confirm that when A = B we are always in case #1 and we always have (A - B) mod 3 > 0 false, so we can throw that possibility out.
if 0 < 3 <= A - B, meaning B < 3 + B <= A or simply A >= 3 + B, then (A - B) mod 3 = (A - B - 3) mod 3. By the hypothesis, A - B - 3 >= 3 + B - B - 3 >= 0, so we are still in either case 1 or 2. If we remain in case 2, we can repeat this until we eventually reach case 1, and we will see that we cannot have A - B - 3k = 0; that is, it cannot be that A = B + 3k for any positive k.
if -3 < A - B < 0, or B - 3 < A < B, then (A - B) mod 3 = A - B. By the hypothesis it is less than zero, and so we must throw out all of these possibilities.
if A - B <= -3 < 0, meaning A <= B - 3 < B or simply A <= B - 3 then (A - B) mod 3 = (A - B + 3) mod 3. By the hypothesis, A - B + 3 <= B - 3 - B + 3 = 0, so we are still in either case 3 or 4. If we remain in case 4, we can repeat this until we eventually reach case 3, and we will see nothing remains.
We cannot be in this case since 3 > 0.
We had to throw out the following strings from our language:
A = B
A = B + 3k
A < B.
So we keep only strings with more a's than b's where A - B is not divisible by 3. Suppose this language were regular. Consider the string (b^p)(a^(p+1)) in the language. By the pumping lemma, we should be able to pump the number of bs; but then we could get more bs than as. So the language cannot be regular.
If we take what is maybe a more usual definition for x mod y (not more correct, necessarily):
x mod y = { x , if 0 <= x < y
(x - y) , if 0 < y <= x
(x + y) mod y , if -y < x < 0
-(-x mod -y) , if y < 0
}
By this definition:
in case 1, we throw out A = B
in case 2, we throw out A = B + 3k
in case 3, we throw out A = B - 3k
since 3 > 0, case 4 doesn't apply
Now we have only thrown out the cases where A mod B = 0 (mod 3). This language is regular and has DFA:
+------------a-------------+
| |
| +---b----+ +---b----+ |
| | | | | |
V V | V | |
(q0)---a--->(q1)---a--->(q2)
--->(q0)
(q0)---b--->(q3)---b--->(q4)
^ ^ | ^ | |
| | | | | |
| +---a----+ +---a----+ |
| |
+------------b-------------+

Taylor series via F#

I'm trying to write Taylor series in F#.
Have a look at my code
let rec iter a b f i =
if a > b then i;
else f a (iter (a+1) b f i)
let sum a b = iter a b (+) 0 // from 0
// e^x = 1 + x + (x^2)/2 + ... (x^n)/n! + ...
let fact n = iter 1 n (*) 1 // factorial
let pow x n = iter 1 n (fun n acc -> acc * x) 1
let exp x =
iter 0 x
(fun n acc ->
acc + (pow x n) / float (fact n)) 0
In the last row I am trying cast int fact n to float, but seems like I'm wrong because this code isn't compileable :(
Am I doing the right algorithm?
Can I call my code functional-first?
The code doesn't compile, because:
You're trying to divide an integer pow x n by a float. Division has to have operands of the same type.
You're specifying the terminal case of the wrong type. Literal 0 is integer. If you want float zero, use 0.0 or abbreviated 0.
Try this:
let exp x =
iter 0 x
(fun n acc ->
acc + float (pow x n) / float (fact n)) 0.
P.S. In the future, please provide the exact error messages and/or unexpected results that you're getting. Simply saying "doesn't work" is not a good description of a problem.

How to define piece-wise functions in Z3py

I would like to define a piece-wise (linear) function in Z3py, for example, the function f(x) has the form
f(x) = a*x + b when 0 <= x <= 1
f(x) = exp(c*x) when 1 < x <= 2
f(x) = 1/(1+10^x) when 2 < x <= 3
etc.
where a, b and c are constants.
I guess the z3.If() function will be relevant, but as the number of pieces grows, the expression gets convoluted.
My questions is, does Z3pyprovides the if-else statement, or is there an elegant way to define piece-wise function in Z3py?
Yes, Z3 supports if-then-elses and in Python they can be constructed using the If function. An example from the documentation of If:
>>> x = Int('x')
>>> y = Int('y')
>>> max = If(x > y, x, y)
max = If(x > y, x, y)

Divide a Point in Elliptic Curve Cryptography

I'm using Elliptic Curve to design a security system. P is a point on elliptic curve. The receiver must obtain P using formula k^-1(kP). The receiver does not know P but knows k. I need to compute k^-1(R) where R=kP. How can I do this using Point Multiplication or Point Addition.
I suggest first learning a bit more about ECC (for example, read some of Paar's book and listen to his course at http://www.crypto-textbook.com/) before tackling something this complex. For this particular question, ask yourself: "What does the inverse of k mean?"
Very interesting question you have! I was happy to implement from scratch Python solution for your task, see code at the bottom of my answer.
Each elliptic curve has an integer order q. If we have any point P on curve then it is well known that q * P = Zero, in other words multiplying any point by order q gives zero-point (infinity point).
Multiplying zero (infinity) point by any number gives zero again, i.e. j * Zero = Zero for any integer j. Adding any point P to zero-point gives P, i.e. Zero + P = P.
In our task we have some k such that R = k * P. We can very easily (very fast) compute Modular Inverse of k modulo order q, using for example Extended Euclidean Algorithm.
Inverse of k modulo q by definition is such that k * k^-1 = 1 (mod q), which by definition of modulus is equal k * k^-1 = j * q + 1 for some integer j.
Then k^-1 * R = k^-1 * k * P = (j * q + 1) * P = j * (q * P) + P = j * Zero + P = Zero + P = P. Thus multiplying R by k^-1 gives P, if k^-1 is inverse of k modulo q.
You can read about point addition and multiplication formulas on this Wiki.
Lets now check our formulas in Python programming language. I decided to implement from scratch simple class ECPoint, which implements all curve operations (addition and multiplication), see code below.
We take any ready-made curve, for example most popular 256-bit curve secp256k1, which is used in Bitcoin. Its parameters can be found here (this doc contains many other popular standard curves), also you can read about this specific curve on Bitcoin Wiki Page.
Following code is fully self-contained Python script, doesn't need any external dependencies and modules. You can run it straight away on any computer. ECPoint class implements all curve arithmetics. Function test() does following operations: we take standard secp256k1 params with some base point G, we compute any random point P = random * G, then we generate random k, compute R = k * P, compute modular inverse k^-1 (mod q) by using function modular_inverse() (which uses extended Euclidean algorithm egcd()), compute found_P = k^-1 * R and check that it is equal to P, i.e. check that k^-1 * R == P, print resulting k^-1 * R. All random values are 256-bit.
Try it online!
def egcd(a, b):
# https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
ro, r, so, s, to, t = a, b, 1, 0, 0, 1
while r != 0:
ro, (q, r) = r, divmod(ro, r)
so, s = s, so - q * s
to, t = t, to - q * t
return ro, so, to
def modular_inverse(a, mod):
# https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
g, s, t = egcd(a, mod)
assert g == 1, 'Value not invertible by modulus!'
return s % mod
class ECPoint:
#classmethod
def Int(cls, x):
return int(x)
#classmethod
def std_point(cls, name):
if name == 'secp256k1':
# https://en.bitcoin.it/wiki/Secp256k1
# https://www.secg.org/sec2-v2.pdf
p = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F
a = 0
b = 7
x = 0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798
y = 0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8
q = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141
else:
assert False
return ECPoint(x, y, a, b, p, q)
def __init__(self, x, y, A, B, N, q, *, prepare = True):
if prepare:
N = self.Int(N)
A, B, x, y, q = [self.Int(e) % N for e in [A, B, x, y, q]]
assert (4 * A ** 3 + 27 * B ** 2) % N != 0
assert (y ** 2 - x ** 3 - A * x - B) % N == 0, (
x, y, A, B, N, (y ** 2 - x ** 3 - A * x) % N)
assert N % 4 == 3
assert y == pow(x ** 3 + A * x + B, (N + 1) // 4, N)
self.A, self.B, self.N, self.x, self.y, self.q = A, B, N, x, y, q
def __add__(self, other):
A, N = self.A, self.N
Px, Py, Qx, Qy = self.x, self.y, other.x, other.y
if Px == Qx and Py == Qy:
s = ((Px * Px * 3 + A) * self.inv(Py * 2, N)) % N
else:
s = ((Py - Qy) * self.inv(Px - Qx, N)) % N
x = (s * s - Px - Qx) % N
y = (s * (Px - x) - Py) % N
return ECPoint(x, y, A, self.B, N, self.q, prepare = False)
def __rmul__(self, other):
other = self.Int(other - 1)
r = self
while True:
if other & 1:
r = r + self
if other == 1:
return r
other >>= 1
self = self + self
#classmethod
def inv(cls, a, n):
return modular_inverse(a, n)
def __repr__(self):
return str(dict(x = self.x, y = self.y, A = self.A,
B = self.B, N = self.N, q = self.q))
def __eq__(self, other):
for i, (a, b) in enumerate([
(self.x, other.x), (self.y, other.y), (self.A, other.A),
(self.B, other.B), (self.N, other.N), (self.q, other.q)]):
if a != b:
return False
return True
def test():
import random
bits = 256
P = random.randrange(1 << bits) * ECPoint.std_point('secp256k1')
k = random.randrange(1 << bits)
R = k * P
found_P = modular_inverse(k, R.q) * R
assert found_P == P
print(found_P)
if __name__ == '__main__':
test()
Output:
{
'x': 108051465657467150531748691374311160382608428790397210924352716318223953013557,
'y': 4462548165448905789984443302412298811224817997977472205419179335194291964455,
'A': 0,
'B': 7,
'N': 115792089237316195423570985008687907853269984665640564039457584007908834671663,
'q': 115792089237316195423570985008687907852837564279074904382605163141518161494337
}

Resources