Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Parameterized Modules] newtype instance has inconsistent type #813

Closed
WeeknightMVP opened this issue Jul 12, 2020 · 2 comments
Closed

[Parameterized Modules] newtype instance has inconsistent type #813

WeeknightMVP opened this issue Jul 12, 2020 · 2 comments

Comments

@WeeknightMVP
Copy link

WeeknightMVP commented Jul 12, 2020

My attempt to apply the instantiated block cipher from Issue #812 to a cipher mode fails:

CBC_.cry

module CBC_ where

import `BlockCipher_ (BlockCipher)

parameter
    type _Key: *
    type _Block: *
    type constraint (Cmp _Block, Logic _Block)

    _blockCipher: BlockCipher _Key _Block


type Key = _Key
type Block = _Block

blockCipher = _blockCipher


type Op n = Key -> Block -> [n]Block -> [n]Block


encrypt: {n} Op n
encrypt k iv ps = cs
  where
    cs = [ blockCipher.encrypt k (p ^ c')
         | p <- ps
         | c' <- [iv] # cs ]

decrypt: {n} Op n
decrypt k iv cs = 
    [ (blockCipher.decrypt k c) ^ c'
    | c <- cs
    | c' <- [iv] # cs ]

_CBC_XOR32.cry

module _CBC_XOR32 = CBC_ where

import XOR32Cipher (blockCipher)

type _Key = [32]
type _Block = [32]

_blockCipher = blockCipher
Cryptol> :m CBC_
Loading module BlockCipher_
Loading module CBC_Cryptol> :m _CBC_XOR32
...
Loading module _CBC_XOR32

[error] at ...\_CBC_XOR32.cry:8:1--8:13:
  Type mismatch:
    Expected type: `BlockCipher_::BlockCipher _CBC_XOR32::_Key
                                              _CBC_XOR32::_Block
    Inferred type: _XOR32Cipher::BlockCipher

Would an analogous blockCipher instantiated from BlockCipher_, as in the Issue #812 crash, have worked? If not, is there a way to encapsulate instances of parameterized modules in this fashion?

@WeeknightMVP
Copy link
Author

Closing as newtype is obsolete, per #815.

@yav
Copy link
Member

yav commented Mar 23, 2023

I think I see what's happening here. The issue is that when you define a newypte in a functor, you get a different newypte for each functor instantiation---this has to happen as the same type can't have different definitions. In fact, when you use a backtick import, the newyptes don't even have the same type parameters (one has 0, one has 2).

Perhaps something like this would work?


submodule BlockCipherWithTypes where                                                
                                                                                    
  parameter                                                                         
    type Key:   *                                                                   
    type Block: *                                                                   
    type constraint Cmp Block                                                       
                                                                                    
  type Op = Key -> Block -> Block                                                   
  newtype BlockCipher = { encrypt: Op, decrypt: Op }                                
                                                                                    
  submodule Ops where                                                               
    parameter                                                                       
      encrypt: Op                                                                   
      decrypt: Op                                                                   
                                                                                    
    blockCipher = BlockCipher { encrypt = encrypt, decrypt = decrypt }              
                                                                                    
submodule Cipher_128_16 = submodule BlockCipherWithTypes where                      
  type Key   = [128]                                                                
  type Block = [16]                                                                 
                                                                                    
import submodule Cipher_128_16 as Cipher_128_16                                     
                                                                                    
submodule NoCipher = submodule Cipher_128_16::Ops where                             
  encrypt key val = val                                                             
  decrypt key val = val                                                             
                                                                                    
                                                                                    
import submodule NoCipher as NoCipher                                               
                                                                                    
example = NoCipher::blockCipher.encrypt 1 2  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants