Generate random number in Haskell

I finally figured out how to create a random number, but the compiler still complains about my code.

the code:

type Quot   = Integer

sign (p,q,g) (x,pub) d =
       do k <- randomRIO(1,q-1 :: Integer)
   ki <- kinv k q
   r <- g^k `mod` p
   s <- (160 + x*r)*ki mod q
   return (r,s)

kinv :: Integer -> Quot -> Integer
kinv k q =
   do (d,t,s) <- gcdE(q,k)
      return s

gcdE(a,0) = (a,1,0)
gcdE(a,b) = (d,t,s - q*t)
    where r = a `mod` b
         q = a `div` b
        (d,s,t) = gcdE(b,r)

Error message:

crypt.hs:24:7:
Couldn't match expected type `Integer' against inferred type `m a'
In a stmt of a 'do' expression: ki <- kinv k q
In the expression:
    do { k <- randomRIO (1, q - 1 :: Integer);
         ki <- kinv k q;
         r <- g ^ k `mod` p;
         s <- (160 + x * r) * ki mod q;
         .... }
In the definition of `sign':
    sign (p, q, g) (x, pub) d
           = do { k <- randomRIO (1, q - 1 :: Integer);
                  ki <- kinv k q;
                  r <- g ^ k `mod` p;
                  .... }

crypt.hs:37:10:
Couldn't match expected type `Integer'
       against inferred type `(Quot, Quot, b)'
In a stmt of a 'do' expression: (d, t, s) <- gcdE (q, k)
In the expression:
    do { (d, t, s) <- gcdE (q, k);
         return s }
In the definition of `kinv':
    kinv k q
           = do { (d, t, s) <- gcdE (q, k);
                  return s }

I want the variable k to take a random integer value between 0 <k <sq. I'm not so good with Haskell, so it took a while. Thank.

+3
source share
3 answers

Since there is nothing monadic in kinvor gcdE, none of them should contain any dos, <-or returns.

( ) <- kinv gcdE. . let result = non-monadic operation, result <- non-monadic operation.

+1

. , do, randomRIO (1, q-1) IO a, IO - , kniv kq integer IO do. .

sign (p,q,g) (x,pub) d = do
   k <- randomRIO(1,q-1)
   let ki =  kinv k q
   let r  =  mod ( g^k) p
   let s  = mod ((160 + x*r)*ki) q
   return (r,s)

kinv k q = s
   where (_,_,s) = gcdE(q,k)

gcdE(a,0) = (a,1,0)
gcdE(a,b) = (d,t,s - q*t)
    where r = a `mod` b
          q = a `div` b
          (d,s,t) = gcdE(b,r)

, -, . - , . Real World Haskell.

+2

sometimes it is recommended to use monads sparingly if you really do not need them in calculations.

sign a@(_,q,_) (x,pub) d = sign' a x <$> randomRIO(1,q-1)

sign' (p,q,g) x k = (r,s)
  where r = mod (g ^ k) p
        s = mod ((160 + x * r) * kinv k q) q

kinv k q = let (_,_,s) = gcdE(q,k) in s

gcdE(a,0) = (a,1,0)
gcdE(a,b) = (d,t,s - q*t)
    where r = a `mod` b
          q = a `div` b
          (d,s,t) = gcdE(b,r)

So, you can even test the sign function more easily if something is strange ...

0
source

Source: https://habr.com/ru/post/1777318/


All Articles