Which type of leftrotation is used by the MD5 hash algorithm? - hash

In this piece of pseudocode from the MD5 Wikipedia website, fully available here, there is a pseudofunction leftrotate().
for each 512-bit chunk of message
break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15
//Initialize hash value for this chunk:
var int A := a0
var int B := b0
var int C := c0
var int D := d0
//Main loop:
for i from 0 to 63
if 0 ≤ i ≤ 15 then
F := (B and C) or ((not B) and D)
g := i
else if 16 ≤ i ≤ 31
F := (D and B) or ((not D) and C)
g := (5×i + 1) mod 16
else if 32 ≤ i ≤ 47
F := B xor C xor D
g := (3×i + 5) mod 16
else if 48 ≤ i ≤ 63
F := C xor (B or (not D))
g := (7×i) mod 16
dTemp := D
D := C
C := B
B := B + leftrotate((A + F + K[i] + M[g]), s[i])
A := dTemp
end for
//Add this chunk's hash to result so far:
a0 := a0 + A
b0 := b0 + B
c0 := c0 + C
d0 := d0 + D
end for
var char digest[16] := a0 append b0 append c0 append d0 //(Output is in little-endian)
//leftrotate function definition
leftrotate (x, c)
return (x << c) binary or (x >> (32-c));
However, is the leftrotate() function a logical rotate or a circular rotate? As when I looked up the function on the bitwise operations wikipedia I saw different leftrotations. Which one does the MD5 hashfunction use?
The rotation is defined on the first Wikipedia as:
leftrotate (x, c)
return (x << c) binary or (x >> (32-c));
On RFC 1321 the function is formulated differently, like so:
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
Where s is the shift, but still I don't know what kind of leftrotate it is.

Found the answer while googling some other questions here
A bit rotation is also known as a circular shift rotation, extra information can be found here:
- Circular shift
- Bitwise operations
A circular shift shifts the numbers to left by an x amount, appending the extra ones back at the end.

Related

Error: Cannot interpret this number as a value of type nat

My current goal is:
x - 1 + 1 = x
I tried to use rewrite -> (Nat.add_comm (-1) 1). to change the current goal to x + 1 - 1, but it gave me the error Error: Cannot interpret this number as a value of type nat. How can I solve this question?
Assuming x is indeed a natural number, I believe your goal is false. Note that subtraction on the natural numbers is truncated. Thus, if x = 0, what we have is
0 - 1 + 1 = (0 - 1) + 1 = 0 + 1 = 1 != 0
where the parenthesis I added are already there, I just made them explicit (*).
The error you get makes perfect sense. -1 is not a natural number, and hence Coq can't interpret it as a natural number.
(*) You can do this with Set Printing Parentheses.
Edit: If you are able to prove that 1 <= x in your context, you can use
Nat.sub_add: forall n m : nat, n <= m -> m - n + n = m
Nat.add_sub_swap: forall n m p : nat, p <= n -> n + m - p = n - p + m
I found these results by importing Arith and searching like so:
Search (_ - _ + _).

parameter passing strategy in a semi-C code

it's a problem in my assignment.
Following code written in semi-C language. Set parameter passing type for f, g and h functions in order to have 29, 34 and 43 at the end of execution.for instance, for acquiring 29 we have to use call-by-value in f,g and h . but I don't know what should I do for 34 and 43?
f(x) {return g(2*x);}
g(x) {let y = 1 in {h(y); return x + y + x;}}
h(x) {x = x + 5; return 0}
main() {printf(f(7));}

Maple: specify variable over which to maximize

This is a very simple question, but found surprisingly very little about it online...
I want to find the minimizer of a function in maple, I am not sure how to indicate which is the variable of interest? Let us take a very simple case, I want the symbolic minimizer of a quadratic expression in x, with parameters a, b and c.
Without specifying something, it does minimize over all variables, a, b, c and x.
f4 := a+b*x+c*x^2
minimize(f4, location)
I tried to specify the variable in the function, did not work either:
f5 :=(x) ->a+b*x+c*x^2
minimize(f5, location)
How should I do this? And, how would I do if I wanted over two variables, x and y?
fxy := a+b*x+c*x^2 + d*y^2 +e*y
f4 := a+b*x+c*x^2:
extrema(f4, {}, x);
/ 2\
|4 a c - b |
< ---------- >
| 4 c |
\ /
fxy := a+b*x+c*x^2 + d*y^2 +e*y:
extrema(fxy, {}, {x,y});
/ 2 2\
|4 a c d - b d - c e |
< --------------------- >
| 4 c d |
\ /
The nature of the extrema will depend upon the values of the parameters. For your first example above (quadratic in x) it will depend on the signum of c.
The command extrema accepts an optional fourth argument, such as an unassigned name (or an uneval-quoted name) to which is assigns the candidate solution points (as a side-effect of its calculation). Eg,
restart;
f4 := a+b*x+c*x^2:
extrema(f4, {}, x, 'cand');
2
4 a c - b
{----------}
4 c
cand;
b
{{x = - ---}}
2 c
fxy := a+b*x+c*x^2 + d*y^2 +e*y:
extrema(fxy, {}, {x,y}, 'cand');
2 2
4 a c d - b d - c e
{---------------------}
4 c d
cand;
b e
{{x = - ---, y = - ---}}
2 c 2 d
Alternatively, you may set up the partial derivatives and solve them manually. Note that for these two examples there is just a one result (for each) returned by solve.
restart:
f4 := a+b*x+c*x^2:
solve({diff(f4,x)},{x});
b
{x = - ---}
2 c
normal(eval(f4,%));
2
4 a c - b
----------
4 c
fxy := a+b*x+c*x^2 + d*y^2 +e*y:
solve({diff(fxy,x),diff(fxy,y)},{x,y});
b e
{x = - ---, y = - ---}
2 c 2 d
normal(eval(fxy,%));
2 2
4 a c d - b d - c e
---------------------
4 c d
The code for the extrema command can be viewed, by issuing the command showstat(extrema). You can see how it accounts for the case of solve returning multiple results.

TypeError: unsupported operand parent(s) for '+': 'Ring of integers modulo x' and 'Ring of integers modulo y'

I am trying to decrypt a RSA message using the Chinese Remainder Theorem:
p = random_prime(2^512-1, False, 2^511)
q = random_prime(2^512-1, False, 2^511)
n = p * q
phi = (p - 1) * (q - 1)
m = 235432543543345
e = 65537
bezout = xgcd(e, phi)
d = Integer(mod(bezout[1], phi))
c = 0
m_decrypted = 0
def encrypt_rsa():
global c
c = mod(m ^ e, n)
print 'c = ', c
def decrypt_rsa_crt():
global m_decrypted
c1 = p * inverse_mod(p % q, q)
c2 = q * inverse_mod(q % p, p)
n1 = ((c % p) ^ (d % (p - 1))) % p
n2 = ((c % q) ^ (d % (q - 1))) % q
m_decrypted = (n1 * c1 + n2 * c2) % n
encrypt_rsa()
decrypt_rsa_crt()
print 'm_decrypted = ', m_decrypted
However I'm getting this error:
Error in lines 40-40
Traceback (most recent call last):
File "/projects/sage/sage-6.9/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 905, in execute
exec compile(block+'\n', '', 'single') in namespace, locals
File "", line 1, in <module>
File "", line 15, in decrypt_rsa_crt
File "sage/structure/element.pyx", line 1700, in sage.structure.element.RingElement.__add__ (/projects/sage/sage-6.9/src/build/cythonized/sage/structure/element.c:16570)
return coercion_model.bin_op(left, right, add)
File "sage/structure/coerce.pyx", line 1070, in sage.structure.coerce.CoercionModel_cache_maps.bin_op (/projects/sage/sage-6.9/src/build/cythonized/sage/structure/coerce.c:9739)
raise TypeError(arith_error_message(x,y,op))
TypeError: unsupported operand parent(s) for '+': 'Ring of integers modulo 13171665913556629928579831399279531345454405227507363358767433731944129138880990155192020899186190552971738190528920869626603617749599336864307309151600773' and 'Ring of integers modulo 7040259687366349269925712273121165166901616380486072254231627613746850969231618371638459623994615760442997840722561781585598181676625437161073288718538017'
The line of the error is the m_decrypted = (n1 * c1 + n2 * c2) % n line. I'm not sure what I'm doing wrong here and how to fix it?
inverse_mod puts things in the ring of integers modulo q or p, in your code. But there is no canonical way to add c1 and c2 since they are in different rings of integers, as the error message indicates. I guess you may want to try to get those to be integers mod n instead, or even better to get just one of the integers.

Selecting k*k subarray from p*p*n array in Fortran

I have a ppn array in Fortran, and I want to extract k*k subarray from that bigger array. I tried like this, but not sure does it work:
do i=1,p
vp(i)=i
end do
help=y(1:p,t)*vp
do t = 1, n
A(1:k,1:k,t) = B(pack(help,help>0), pack(help,help>0), t)
end do
where y contains values 0 and 1, 1 meaning that row/column is wanted to subarray. Does that work, and if not, how that same thing could be archieved? Thanks.
If I understand what you want to do, here is an example program that extracts selected columns and rows, but not using much array notation.
program test
integer, parameter :: Adim = 2
integer, parameter :: Bdim = 3
integer, dimension (Adim,Adim) :: A
integer, dimension (Bdim,Bdim) :: B
logical, dimension (Bdim) :: good_row = [.true., .false., .true.]
logical, dimension (Bdim) :: good_col = [.false., .true., .true.]
integer :: i, j, ia, ja, ib, jb
if (count (good_row) /= Adim .or. count (good_col) /= Adim) then
write (*, *) 'selection arrays not setup correctly.'
stop
end if
do i=1, Bdim
do j=1, Bdim
B (i,j) = i + i*j**2 ! test values
end do
end do
do i=1, Bdim
write (*, *) (B (i, j), j=1, Bdim)
end do
ia = 0
do ib=1, Bdim
if (good_row (ib)) then
ia = ia + 1
ja = 0
do jb=1, Bdim
if (good_col (jb)) then
ja = ja + 1
!write (*, *) ia, ja, ib, jb
A(ia,ja) = B(ib,jb)
end if
end do
end if
end do
write (*, *)
do i=1, Adim
write (*, *) (A (i, j), j=1, Adim)
end do
stop
end program test
Solution two, using array operations at the vector (1D array) level -- replace the main loop with:
ia = 0
do ib=1, Bdim
if (good_row (ib)) then
ia = ia + 1
A (ia,:) = pack (B(ib,:), good_col)
end if
end do
Solution three, fully using array operations:
program test
integer, parameter :: Adim = 2
integer, parameter :: Bdim = 3
integer, dimension (Adim,Adim) :: A
integer, dimension (Bdim,Bdim) :: B
logical, dimension (Bdim,Bdim) :: mask
integer :: i, j
mask (1,:) = [.false., .true., .true.]
mask (2,:) = .false.
mask (3,:) = [.false., .true., .true.]
do i=1, Bdim
do j=1, Bdim
B (i,j) = i + i*j**2 ! test values
end do
end do
do i=1, Bdim
write (*, *) (B (i, j), j=1, Bdim)
end do
A = reshape ( pack (B, mask), [Adim, Adim] )
write (*, *)
do i=1, Adim
write (*, *) (A (i, j), j=1, Adim)
end do
stop
end program test
Not sure if these fragments of non-code are any use to you but;
Don't forget the array sectioning features of Fortran.
Don't forget that you can use vector subscripts to get array sections, for example, you might select elements of a vector v like this:
v( (/1, 3, 6, 5, 10 /) )
Vector subscripting can be applied to arrays of rank greater than 1. It would hurt my head to figure out your subscripting requirements this way, but you might want to try it.
Yes it should work, and you even do not need the do t = ... loop
program main
integer,dimension(3,3,2):: a
integer,dimension(4,4,2):: b
integer,dimension(4):: y
integer,dimension(4):: idx
integer:: i,j,k
y = (/ 1 , 0 , 1 , 1 /)
idx = (/ (i,i=1,4) /)
b(:,:,:)=reshape((/((((i+10*j+100*k),i=1,4),j=1,4),k=1,2)/),(/4,4,2/))
a(:,:,:) = b( pack(idx,y>0) , pack(idx,y>0) , :)
print '(A2/,(4I4))','b=',b
print '(A2/,(3I4))','a=',a
end
compiled with gfortran 4.2.3 correctly gives me
b=
111 112 113 114
121 122 123 124
131 132 133 134
141 142 143 144
211 212 213 214
221 222 223 224
231 232 233 234
241 242 243 244
a=
111 113 114
131 133 134
141 143 144
211 213 214
231 233 234
241 243 244
You could also use
k = count( y> 0)
a(1:k,1:k,:) = b( pack(idx,y>0) , pack(idx,y>0) , :)
Or think using LOGICAL .true. and .false. instead of 1 and 0...
program main
integer,dimension(3,3,2):: a
integer,dimension(4,4,2):: b
logical,dimension(4):: y
integer,dimension(4):: idx
integer:: i,j,k
idx = (/ (i,i=1,4) /)
y = idx /= 2
b(:,:,:)=reshape((/((((i+10*j+100*k),i=1,4),j=1,4),k=1,2)/),(/4,4,2/))
k = count( y )
a(1:k,1:k,:) = b( pack(idx,y) , pack(idx,y) , :)
print '(A2/,(4I4))','b=',b
print '(A2/,(3I4))','a=',a
end